w-web-perm 1.0.71 → 1.0.72

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 (82) hide show
  1. package/dist/css/app.c0e03d41.css +1 -0
  2. package/dist/index.tmp +1 -1
  3. package/dist/js/{app-legacy.a8a679a7.js → app-legacy.9564c1ab.js} +1 -1
  4. package/dist/js/{app.a8a679a7.js → app.9564c1ab.js} +1 -1
  5. package/dist/js/{chunk-vendors.644eda7c.js → chunk-vendors-legacy.778356e3.js} +1 -1
  6. package/dist/js/{chunk-vendors-legacy.644eda7c.js → chunk-vendors.778356e3.js} +1 -1
  7. package/dist/w-web-perm.umd.js +2 -2
  8. package/dist/w-web-perm.umd.js.map +1 -1
  9. package/docs/WWebPerm.html +122 -2
  10. package/docs/WWebPerm.mjs.html +6 -3
  11. package/docs/index.html +1 -1
  12. package/package.json +13 -13
  13. package/server/WWebPerm.mjs +5 -2
  14. package/server/procLang.mjs +0 -12
  15. package/server/procStaInfor.mjs +19 -10
  16. package/server/srLog.mjs +14 -5
  17. package/server/staLogs/staEvent.callWorker.mjs +5 -40
  18. package/server/staLogs/staEvent.mjs +6 -112
  19. package/server/staLogs/staEventTable.callWorker.mjs +11 -0
  20. package/server/staLogs/staEventTable.mjs +6 -96
  21. package/server/staLogs/staLogsCore.callWorker.mjs +89 -0
  22. package/server/staLogs/staLogsCore.mjs +554 -0
  23. package/server/staLogs/staLogsCore.shellWorker.mjs +28 -0
  24. package/settings.json +1 -0
  25. package/src/components/LayoutContentStaInfor.vue +45 -73
  26. package/tableTags.json +1 -1
  27. package/dist/css/app.5a2ba039.css +0 -1
  28. package/logs/2026-06-19T16.log +0 -191
  29. package/logs/2026-06-19T23.log +0 -0
  30. package/logs/2026-06-20T00.log +0 -207
  31. package/logs/2026-06-20T11.log +0 -221
  32. package/logs/2026-06-20T12.log +0 -146
  33. package/logs/2026-06-20T13.log +0 -134
  34. package/logs/2026-06-20T14.log +0 -296
  35. package/logs/2026-06-20T15.log +0 -225
  36. package/logs/2026-06-20T16.log +0 -174
  37. package/logs/2026-06-21T16.log +0 -110
  38. package/logs/2026-06-21T17.log +0 -301
  39. package/logs/2026-06-21T18.log +0 -238
  40. package/logs/2026-06-21T19.log +0 -141
  41. package/logs/2026-06-21T20.log +0 -99
  42. package/logs/2026-06-21T21.log +0 -143
  43. package/logs/2026-06-21T23.log +0 -26
  44. package/logs/2026-06-22T00.log +0 -33
  45. package/logs/2026-06-22T08.log +0 -235
  46. package/logs/2026-06-22T09.log +0 -246
  47. package/logs/2026-06-22T10.log +0 -301
  48. package/logs/2026-06-22T11.log +0 -140
  49. package/logs/2026-06-22T12.log +0 -22
  50. package/logs/2026-06-22T14.log +0 -44
  51. package/logs/2026-06-22T23.log +0 -951
  52. package/logs/2026-06-23T00.log +0 -263
  53. package/logs/2026-06-23T08.log +0 -611
  54. package/logs/2026-06-30T21.log +0 -3609
  55. package/logs/2026-06-30T22.log +0 -3682
  56. package/logs/2026-06-30T23.log +0 -592
  57. package/logs/2026-07-01T12.log +0 -0
  58. package/logs/2026-07-09T22.log +0 -2220
  59. package/logs/2026-07-09T23.log +0 -1140
  60. package/logs/2026-07-10T12.log +0 -6
  61. package/logs/2026-07-10T13.log +0 -351
  62. package/logs/2026-07-10T16.log +0 -1272
  63. package/logs/2026-07-10T19.log +0 -6
  64. package/logs/2026-07-10T20.log +0 -1883
  65. package/logs/2026-07-10T21.log +0 -3505
  66. package/logs/2026-07-10T22.log +0 -3395
  67. package/logs/2026-07-11T00.log +0 -1338
  68. package/logs/2026-07-11T01.log +0 -2492
  69. package/logs/2026-07-11T17.log +0 -19
  70. package/logs/2026-08-25T19.log +0 -4704
  71. package/logs/2026-08-25T20.log +0 -5144
  72. package/logs/2026-08-25T21.log +0 -2116
  73. package/logs/2026-08-26T05.log +0 -1678
  74. package/logs/2026-08-26T06.log +0 -4561
  75. package/logs/2026-08-26T07.log +0 -4916
  76. package/logs/2026-08-26T08.log +0 -260
  77. package/logs/2026-08-26T09.log +0 -1543
  78. package/logs/2026-08-26T13.log +0 -2559
  79. package/logs/2026-08-26T14.log +0 -5526
  80. package/logs/2026-08-26T15.log +0 -2271
  81. package/server/staLogs/staEvent.shellWorker.mjs +0 -19
  82. package/z/344/277/256/346/255/243/350/246/217/345/212/203/346/233/270.md +0 -450
@@ -80,7 +80,7 @@
80
80
 
81
81
  <dt class="tag-source">Source:</dt>
82
82
  <dd class="tag-source"><ul class="dummy"><li>
83
- <a href="WWebPerm.mjs.html">WWebPerm.mjs</a>, <a href="WWebPerm.mjs.html#line137">line 137</a>
83
+ <a href="WWebPerm.mjs.html">WWebPerm.mjs</a>, <a href="WWebPerm.mjs.html#line140">line 140</a>
84
84
  </li></ul></dd>
85
85
 
86
86
 
@@ -837,6 +837,126 @@
837
837
  </tr>
838
838
 
839
839
 
840
+
841
+ <tr>
842
+
843
+ <td class="name"><code>logFd</code></td>
844
+
845
+
846
+ <td class="type">
847
+
848
+
849
+ <span class="param-type">String</span>
850
+
851
+
852
+
853
+
854
+ </td>
855
+
856
+
857
+ <td class="attributes">
858
+
859
+ &lt;optional><br>
860
+
861
+
862
+
863
+
864
+
865
+ </td>
866
+
867
+
868
+
869
+ <td class="default">
870
+
871
+ <code>'./logs'</code>
872
+
873
+ </td>
874
+
875
+
876
+ <td class="description last"><p>輸入log紀錄儲存位置字串,預設'./logs'</p></td>
877
+ </tr>
878
+
879
+
880
+
881
+ <tr>
882
+
883
+ <td class="name"><code>logInterval</code></td>
884
+
885
+
886
+ <td class="type">
887
+
888
+
889
+ <span class="param-type">String</span>
890
+
891
+
892
+
893
+
894
+ </td>
895
+
896
+
897
+ <td class="attributes">
898
+
899
+ &lt;optional><br>
900
+
901
+
902
+
903
+
904
+
905
+ </td>
906
+
907
+
908
+
909
+ <td class="default">
910
+
911
+ <code>'hr'</code>
912
+
913
+ </td>
914
+
915
+
916
+ <td class="description last"><p>輸入log紀錄檔案拆檔時長字串,可選'hr'或'day',預設'hr'</p></td>
917
+ </tr>
918
+
919
+
920
+
921
+ <tr>
922
+
923
+ <td class="name"><code>logNumKeep</code></td>
924
+
925
+
926
+ <td class="type">
927
+
928
+
929
+ <span class="param-type">Integer</span>
930
+
931
+
932
+
933
+
934
+ </td>
935
+
936
+
937
+ <td class="attributes">
938
+
939
+ &lt;optional><br>
940
+
941
+
942
+
943
+
944
+
945
+ </td>
946
+
947
+
948
+
949
+ <td class="default">
950
+
951
+ <code>null</code>
952
+
953
+ </td>
954
+
955
+
956
+ <td class="description last"><p>輸入log檔保留數上限正整數,超出者自最舊刪除,未給採w-syslog預設(hr模式365*24、day模式365),預設null</p></td>
957
+ </tr>
958
+
959
+
840
960
  </tbody>
841
961
  </table>
842
962
 
@@ -925,7 +1045,7 @@
925
1045
  <br class="clear">
926
1046
 
927
1047
  <footer>
928
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Aug 31 2026 17:10:51 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
1048
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Wed Sep 02 2026 00:36:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
929
1049
  </footer>
930
1050
 
931
1051
  <script>prettyPrint();</script>
@@ -101,6 +101,9 @@ import procStaInfor from './procStaInfor.mjs'
101
101
  * @param {String} [opt.subfolder=''] 輸入站台所在子目錄字串,提供站台位於內網採反向代理進行服務時,故需支援位於子目錄情形,預設''
102
102
  * @param {String} [opt.urlRedirect=''] 輸入錯誤時自動轉址字串,提供站台例如無法登入或驗證失敗時須自動轉址,預設''
103
103
  * @param {String} [opt.mappingBy='email'] 輸入外部系統識別使用者token後所提供之資料物件,與權限系統之使用者資料物件,兩者間查找之對應欄位,可選'id'、'email'、'name',預設'email'
104
+ * @param {String} [opt.logFd='./logs'] 輸入log紀錄儲存位置字串,預設'./logs'
105
+ * @param {String} [opt.logInterval='hr'] 輸入log紀錄檔案拆檔時長字串,可選'hr'或'day',預設'hr'
106
+ * @param {Integer} [opt.logNumKeep=null] 輸入log檔保留數上限正整數,超出者自最舊刪除,未給採w-syslog預設(hr模式365*24、day模式365),預設null
104
107
  * @returns {Object} 回傳物件,其內server為hapi伺服器實體,wsrv為w-converhp的伺服器事件物件,wsds為w-serv-webdata的伺服器事件物件,可監聽error事件
105
108
  * @example
106
109
  *
@@ -348,9 +351,9 @@ function WWebPerm(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser
348
351
  //procStaInfor: 統計資訊, fdLog 對齊 srLog 使用同一目錄(讀 settings.logFd, fallback 邏輯同 srLog.mjs); mock 由 settings.staEventMock 注入(e2e 統計圖穩定用)
349
352
  let logFd = get(opt, 'logFd', '')
350
353
  if (!isestr(logFd)) {
351
- logFd = './_logs'
354
+ logFd = './logs'
352
355
  }
353
- let psi = procStaInfor({ fdLog: logFd, mock: get(opt, 'staEventMock', false) })
356
+ let psi = procStaInfor({ fdLog: logFd, mock: get(opt, 'staEventMock', false), srLog })
354
357
 
355
358
 
356
359
  //getWebInfor
@@ -1228,7 +1231,7 @@ export default WWebPerm
1228
1231
  <br class="clear">
1229
1232
 
1230
1233
  <footer>
1231
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Aug 31 2026 17:10:51 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
1234
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Wed Sep 02 2026 00:36:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
1232
1235
  </footer>
1233
1236
 
1234
1237
  <script>prettyPrint();</script>
package/docs/index.html CHANGED
@@ -71,7 +71,7 @@
71
71
  <br class="clear">
72
72
 
73
73
  <footer>
74
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Aug 31 2026 17:10:51 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
74
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Wed Sep 02 2026 00:36:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
75
75
  </footer>
76
76
 
77
77
  <script>prettyPrint();</script>
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "w-web-perm",
3
- "version": "1.0.71",
3
+ "version": "1.0.72",
4
4
  "main": "dist/w-web-perm.umd.js",
5
5
  "dependencies": {
6
6
  "axios": "^1.18.1",
7
7
  "json5": "^2.2.3",
8
- "w-aggrid-vue": "^2.0.76",
9
- "w-component-vue": "^2.5.6",
10
- "w-data-collector": "^1.0.33",
11
- "w-echarts-vue": "^1.0.5",
12
- "w-serv-hapi": "^1.0.83",
13
- "w-serv-orm": "^1.0.50",
14
- "w-syslog": "^1.0.22",
15
- "w-ui-loginout": "^1.0.21",
16
- "wsemi": "^1.8.80"
8
+ "w-aggrid-vue": "^2.0.77",
9
+ "w-component-vue": "^2.5.8",
10
+ "w-data-collector": "^1.0.34",
11
+ "w-echarts-vue": "^1.0.6",
12
+ "w-serv-hapi": "^1.0.84",
13
+ "w-serv-orm": "^1.0.51",
14
+ "w-syslog": "^1.0.23",
15
+ "w-ui-loginout": "^1.0.22",
16
+ "wsemi": "^1.8.81"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@vue/cli-plugin-babel": "^5.0.8",
@@ -28,15 +28,15 @@
28
28
  "eslint-plugin-vue": "^9.10.0",
29
29
  "vue": "^2.7.16",
30
30
  "vuex": "^3.6.2",
31
- "w-orm-lmdb": "^1.0.27",
31
+ "w-orm-lmdb": "^1.0.28",
32
32
  "w-package-tools": "^1.1.15",
33
33
  "w-package-tools-e2e": "^1.0.0",
34
- "w-screenctl": "^1.0.15"
34
+ "w-screenctl": "^1.0.16"
35
35
  },
36
36
  "scripts": {
37
37
  "serve": "vue-cli-service serve",
38
38
  "build": "vue-cli-service build",
39
- "test:unit": "mocha test/unit-staEvent.test.mjs --timeout 300000",
39
+ "test:unit": "mocha test/unit-*.test.mjs --timeout 300000",
40
40
  "test:apiunit": "mocha test/unit-*.test.mjs test/api-*.test.mjs test/getUserRules.test.mjs --timeout 300000",
41
41
  "test:e2e": "node test/run-e2e-isolated.mjs",
42
42
  "test": "npm run test:apiunit && npm run test:e2e",
@@ -54,6 +54,9 @@ import procStaInfor from './procStaInfor.mjs'
54
54
  * @param {String} [opt.subfolder=''] 輸入站台所在子目錄字串,提供站台位於內網採反向代理進行服務時,故需支援位於子目錄情形,預設''
55
55
  * @param {String} [opt.urlRedirect=''] 輸入錯誤時自動轉址字串,提供站台例如無法登入或驗證失敗時須自動轉址,預設''
56
56
  * @param {String} [opt.mappingBy='email'] 輸入外部系統識別使用者token後所提供之資料物件,與權限系統之使用者資料物件,兩者間查找之對應欄位,可選'id'、'email'、'name',預設'email'
57
+ * @param {String} [opt.logFd='./logs'] 輸入log紀錄儲存位置字串,預設'./logs'
58
+ * @param {String} [opt.logInterval='hr'] 輸入log紀錄檔案拆檔時長字串,可選'hr'或'day',預設'hr'
59
+ * @param {Integer} [opt.logNumKeep=null] 輸入log檔保留數上限正整數,超出者自最舊刪除,未給採w-syslog預設(hr模式365*24、day模式365),預設null
57
60
  * @returns {Object} 回傳物件,其內server為hapi伺服器實體,wsrv為w-converhp的伺服器事件物件,wsds為w-serv-webdata的伺服器事件物件,可監聽error事件
58
61
  * @example
59
62
  *
@@ -301,9 +304,9 @@ function WWebPerm(WOrm, url, db, getUserByToken, verifyClientUser, verifyAppUser
301
304
  //procStaInfor: 統計資訊, fdLog 對齊 srLog 使用同一目錄(讀 settings.logFd, fallback 邏輯同 srLog.mjs); mock 由 settings.staEventMock 注入(e2e 統計圖穩定用)
302
305
  let logFd = get(opt, 'logFd', '')
303
306
  if (!isestr(logFd)) {
304
- logFd = './_logs'
307
+ logFd = './logs'
305
308
  }
306
- let psi = procStaInfor({ fdLog: logFd, mock: get(opt, 'staEventMock', false) })
309
+ let psi = procStaInfor({ fdLog: logFd, mock: get(opt, 'staEventMock', false), srLog })
307
310
 
308
311
 
309
312
  //getWebInfor
@@ -918,18 +918,6 @@ let kpLang = {
918
918
  eng: `Daily`,
919
919
  cht: `每日`,
920
920
  },
921
- staSelectEvents: {
922
- eng: `Events`,
923
- cht: `事件`,
924
- },
925
- staSelectAll: {
926
- eng: `Select all`,
927
- cht: `全選`,
928
- },
929
- staClear: {
930
- eng: `Clear`,
931
- cht: `清除`,
932
- },
933
921
  staTotal: {
934
922
  eng: `Total`,
935
923
  cht: `全部加總`,
@@ -3,7 +3,7 @@ import get from 'lodash-es/get.js'
3
3
  import isestr from 'wsemi/src/isestr.mjs'
4
4
  import cache from 'wsemi/src/cache.mjs'
5
5
  import staEvent from './staLogs/staEvent.callWorker.mjs'
6
- import staEventTable from './staLogs/staEventTable.mjs'
6
+ import staEventTable from './staLogs/staEventTable.callWorker.mjs'
7
7
 
8
8
 
9
9
  //mock 確定性資料集(供 e2e 統計圖穩定用):固定起點時間 + 固定 sin 計數,不依 now / log → 每次完全相同。
@@ -49,7 +49,7 @@ function proc(opt = {}) {
49
49
  //fdLog
50
50
  let fdLog = get(opt, 'fdLog', '')
51
51
  if (!isestr(fdLog)) {
52
- fdLog = './_logs'
52
+ fdLog = './logs'
53
53
  }
54
54
 
55
55
 
@@ -57,6 +57,10 @@ function proc(opt = {}) {
57
57
  let mock = get(opt, 'mock', false)
58
58
 
59
59
 
60
+ //srLog(staLogsCore 單檔略過時記 warn)
61
+ let srLog = get(opt, 'srLog', null)
62
+
63
+
60
64
  //getStaEvent
61
65
  let _getStaEvent = async (timeLength = 7, timeInterval = 'hr') => {
62
66
 
@@ -66,7 +70,7 @@ function proc(opt = {}) {
66
70
  }
67
71
 
68
72
  //staEvent
69
- let rs = await staEvent(timeLength, timeInterval, { fdLog })
73
+ let rs = await staEvent(timeLength, timeInterval, { fdLog, srLog })
70
74
 
71
75
  return rs
72
76
  }
@@ -76,10 +80,13 @@ function proc(opt = {}) {
76
80
  //cacheKey: 含 timeLength + timeInterval 避免不同分組互蓋快取
77
81
  let cacheKey = `${timeLength}:${timeInterval}`
78
82
 
79
- let r = await ocGetStaEvent.getProxy(cacheKey, { fun: _getStaEvent, inputs: [timeLength, timeInterval], timeExpired: 30 * 1000 }) //快取30秒
83
+ //wsemi ≥1.8.81 cache: 執行中共用 in-flight promise (併發不輪詢); timeFrom:'end' 使 30 秒自掃描完成起算; cacheError:false 失敗不快取且拋錯
84
+ //(取代原「非陣列即 clear + reject」之繞道), 失敗一律 reject 'cannotGetStaEvent' 讓上層 (kpFunExt) 記 err key
85
+ let r = await ocGetStaEvent.getProxy(cacheKey, { fun: _getStaEvent, inputs: [timeLength, timeInterval], timeExpired: 30 * 1000, timeFrom: 'end', cacheError: false }) //快取30秒
86
+ .catch(() => {
87
+ return Promise.reject('cannotGetStaEvent')
88
+ })
80
89
  if (!Array.isArray(r)) {
81
- //_getStaEvent(worker) 失敗時 cache 之 .catch 會回 undefined 並把 undefined 快取 30s; 清除該快取避免窗內重試仍拿 undefined, 並 reject 讓上層 (kpFunExt) 記 err key
82
- ocGetStaEvent.clear(cacheKey)
83
90
  return Promise.reject('cannotGetStaEvent')
84
91
  }
85
92
  return r
@@ -95,17 +102,19 @@ function proc(opt = {}) {
95
102
  }
96
103
 
97
104
  //staEventTable
98
- let rs = await staEventTable({ fdLog })
105
+ let rs = await staEventTable({ fdLog, srLog })
99
106
 
100
107
  return rs
101
108
  }
102
109
  let ocGetStaEventTable = cache()
103
110
  let getStaEventTable = async (userId) => {
104
111
 
105
- let r = await ocGetStaEventTable.getProxy('staEventTable', { fun: _getStaEventTable, inputs: [], timeExpired: 30 * 1000 }) //快取30秒
112
+ //cache 選項同 getStaEvent
113
+ let r = await ocGetStaEventTable.getProxy('staEventTable', { fun: _getStaEventTable, inputs: [], timeExpired: 30 * 1000, timeFrom: 'end', cacheError: false }) //快取30秒
114
+ .catch(() => {
115
+ return Promise.reject('cannotGetStaEventTable')
116
+ })
106
117
  if (!Array.isArray(r)) {
107
- //同 getStaEvent: staEventTable 失敗時 cache 回 undefined 並快取 30s; 清除避免窗內重試仍拿 undefined, 並 reject 讓上層記 err key
108
- ocGetStaEventTable.clear('staEventTable')
109
118
  return Promise.reject('cannotGetStaEventTable')
110
119
  }
111
120
  return r
package/server/srLog.mjs CHANGED
@@ -1,5 +1,7 @@
1
1
  import get from 'lodash-es/get.js'
2
2
  import isestr from 'wsemi/src/isestr.mjs'
3
+ import ispint from 'wsemi/src/ispint.mjs'
4
+ import cint from 'wsemi/src/cint.mjs'
3
5
  import WSyslog from 'w-syslog/src/WSyslog.mjs'
4
6
 
5
7
 
@@ -7,7 +9,7 @@ let init = (opt = {}) => {
7
9
 
8
10
  let fdLog = get(opt, 'logFd', '')
9
11
  if (!isestr(fdLog)) {
10
- fdLog = './_logs'
12
+ fdLog = './logs'
11
13
  }
12
14
 
13
15
  let interval = get(opt, 'logInterval', '')
@@ -15,10 +17,17 @@ let init = (opt = {}) => {
15
17
  interval = 'hr'
16
18
  }
17
19
 
18
- let srLog = WSyslog({
19
- fdLog,
20
- interval,
21
- })
20
+ //numKeep, settings 之 logNumKeep (opt-in): 未給採 w-syslog 預設 (hr: 365*24, day: 365), 有給但非正整數視為設定錯誤
21
+ let numKeep = get(opt, 'logNumKeep', null)
22
+ let o = { fdLog, interval }
23
+ if (numKeep !== null && numKeep !== undefined && numKeep !== '') {
24
+ if (!ispint(numKeep)) {
25
+ throw new Error(`invalid logNumKeep[${numKeep}], must be positive integer`)
26
+ }
27
+ o.numKeep = cint(numKeep)
28
+ }
29
+
30
+ let srLog = WSyslog(o)
22
31
  // srLog.info({ event: 'runner', msg: 'start' })
23
32
  // srLog.warn({ event: 'monitor-memory', msg: 'usage-high', ratio: 85.4 })
24
33
  // srLog.error({ event: 'crash', msg: 'db connection', code: 500 })
@@ -1,46 +1,11 @@
1
- import { fileURLToPath } from 'url'
2
- import path from 'path'
3
- import { Worker } from 'worker_threads'
4
- import genPm from 'wsemi/src/genPm.mjs'
1
+ import { staLogs } from './staLogsCore.callWorker.mjs'
5
2
 
6
3
 
7
- let __filename = fileURLToPath(import.meta.url)
8
- let __dirname = path.dirname(__filename)
9
-
10
- //worker 版 staEvent:於獨立 worker thread 計算(避免讀大量 log 阻塞主執行緒)。介面同 staEvent.mjs。
4
+ //staEvent (worker 版): 掃描交由 staLogsCore 單一 worker (只收需重掃之檔案清單), 快取與 single-flight 在主執行緒; 介面同 staEvent.mjs
11
5
  async function staEvent(timeLength = 7, timeInterval = 'hr', opt = {}) {
12
- let pm = genPm()
13
-
14
- //fpWk
15
- let fpWk = path.resolve(__dirname, 'staEvent.shellWorker.mjs')
16
-
17
- //wk
18
- let wk = new Worker(fpWk)
19
-
20
- wk.on('message', (msg) => {
21
-
22
- if (msg.mode === 'done') {
23
- pm.resolve(msg.payload)
24
- }
25
- else if (msg.mode === 'error') {
26
- pm.reject(msg.payload)
27
- }
28
-
29
- wk.terminate()
30
-
31
- })
32
-
33
- wk.on('error', (err) => {
34
- pm.reject(err)
35
- })
36
-
37
- wk.postMessage({
38
- timeLength,
39
- timeInterval,
40
- opt,
41
- })
42
-
43
- return pm
6
+ let r = await staLogs(timeLength, timeInterval, opt)
7
+ return r.rs
44
8
  }
45
9
 
10
+
46
11
  export default staEvent
@@ -1,118 +1,12 @@
1
- import ot from 'dayjs'
2
- import get from 'lodash-es/get.js'
3
- import size from 'lodash-es/size.js'
4
- import groupBy from 'lodash-es/groupBy.js'
5
- import each from 'lodash-es/each.js'
6
- import mapValues from 'lodash-es/mapValues.js'
7
- import merge from 'lodash-es/merge.js'
8
- import genPm from 'wsemi/src/genPm.mjs'
9
- import isestr from 'wsemi/src/isestr.mjs'
10
- import fsTreeFolder from 'wsemi/src/fsTreeFolder.mjs'
11
- import fsBuildReadStreamText from 'wsemi/src/fsBuildReadStreamText.mjs'
12
- import filterVpfsByWindow from './filterVpfsByWindow.mjs'
1
+ import { staLogs } from './staLogsCore.mjs'
13
2
 
14
3
 
15
- //統計各 event 事件於各時間桶之發生頻率(鏡像 SSO staLogs/staToken.mjs;差異:不限特定 event,改依 event 名分組)。
16
- //回傳: [{ time, data: { count, <event1>: n, <event2>: m, ... } }, ...](count 為該時間桶全部事件數)
4
+ //staEvent: 各 event 於各時間桶之發生頻率, 由 staLogsCore 單趟掃描 + 檔級彙總快取取得; 簽章與輸出形狀不變
5
+ //回傳: [{ time, data: { count, <event1>: n, <event2>: m, ... } }, ...] (count 為該時間桶全部事件數)
17
6
  async function staEvent(timeLength = 7, timeInterval = 'hr', opt = {}) {
18
-
19
- //fdLog
20
- let fdLog = get(opt, 'fdLog')
21
- if (!isestr(fdLog)) {
22
- fdLog = './_logs'
23
- }
24
-
25
- //fmt
26
- let fmt = timeInterval === 'day' ? 'YYYY-MM-DD' : 'YYYY-MM-DDTHH'
27
-
28
- //unit
29
- let unit = timeInterval === 'hr' ? 'hour' : 'day'
30
-
31
- //kpTime, 產生完整的時間區間
32
- let now = ot()
33
- let tStart = now.subtract(timeLength, 'day')
34
- let tCurr = tStart.startOf(unit)
35
- let tEnd = now.startOf(unit)
36
- let kpTime = {}
37
- while (!tCurr.isAfter(tEnd)) {
38
- kpTime[tCurr.format(fmt)] = { data: { count: 0 } }
39
- tCurr = tCurr.add(1, unit)
40
- }
41
-
42
- //vpfs
43
- let vpfs = fsTreeFolder(fdLog)
44
- vpfs = filterVpfsByWindow(vpfs, tStart, fmt) //開檔前剔除窗外檔, 見該模組註解
45
-
46
- //logs
47
- let logs = []
48
- for (let vpf of vpfs) {
49
-
50
- //fp
51
- let fp = vpf.path
52
-
53
- //ev
54
- let ev = fsBuildReadStreamText(fp)
55
-
56
- //line
57
- ev.on('line', (line) => {
58
- let v = null
59
- try {
60
- v = JSON.parse(line)
61
- let t = ot(v.time)
62
- let timeFmt = t.format(fmt)
63
- let b1 = t.isAfter(tStart)
64
- let b2 = isestr(v.event) //有 event 欄位即計入(不限特定 event)
65
- let b = b1 && b2
66
- if (b) {
67
- logs.push({
68
- timeFmt,
69
- ...v,
70
- })
71
- }
72
- }
73
- catch (err) {}
74
- })
75
-
76
- //await close
77
- let pm = genPm()
78
- ev.on('close', () => {
79
- pm.resolve()
80
- })
81
- await pm
82
-
83
- }
84
-
85
- //gs
86
- let gs = groupBy(logs, 'timeFmt')
87
-
88
- //gsLog, 各時間桶內依 event 名分組計數
89
- let gsLog = mapValues(gs, vs => {
90
- let count = size(vs)
91
- let geve = groupBy(vs, 'event')
92
- let kp = {}
93
- each(geve, (vvs, event) => {
94
- kp[event] = size(vvs)
95
- })
96
- return {
97
- data: {
98
- count,
99
- ...kp,
100
- }
101
- }
102
- })
103
-
104
- //merge
105
- let mr = merge({}, kpTime, gsLog)
106
-
107
- //rs
108
- let rs = Object.keys(mr)
109
- .sort()
110
- .map(time => ({
111
- time,
112
- ...mr[time]
113
- }))
114
-
115
- return rs
7
+ let r = await staLogs(timeLength, timeInterval, opt)
8
+ return r.rs
116
9
  }
117
10
 
11
+
118
12
  export default staEvent
@@ -0,0 +1,11 @@
1
+ import { staTable } from './staLogsCore.callWorker.mjs'
2
+
3
+
4
+ //staEventTable (worker 版): 近 25 小時檔案之掃描交由 staLogsCore 單一 worker (主執行緒不阻塞); 介面同 staEventTable.mjs
5
+ async function staEventTable(opt = {}) {
6
+ let r = await staTable(opt)
7
+ return r.rs
8
+ }
9
+
10
+
11
+ export default staEventTable