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.
- package/dist/css/app.c0e03d41.css +1 -0
- package/dist/index.tmp +1 -1
- package/dist/js/{app-legacy.a8a679a7.js → app-legacy.9564c1ab.js} +1 -1
- package/dist/js/{app.a8a679a7.js → app.9564c1ab.js} +1 -1
- package/dist/js/{chunk-vendors.644eda7c.js → chunk-vendors-legacy.778356e3.js} +1 -1
- package/dist/js/{chunk-vendors-legacy.644eda7c.js → chunk-vendors.778356e3.js} +1 -1
- package/dist/w-web-perm.umd.js +2 -2
- package/dist/w-web-perm.umd.js.map +1 -1
- package/docs/WWebPerm.html +122 -2
- package/docs/WWebPerm.mjs.html +6 -3
- package/docs/index.html +1 -1
- package/package.json +13 -13
- package/server/WWebPerm.mjs +5 -2
- package/server/procLang.mjs +0 -12
- package/server/procStaInfor.mjs +19 -10
- package/server/srLog.mjs +14 -5
- package/server/staLogs/staEvent.callWorker.mjs +5 -40
- package/server/staLogs/staEvent.mjs +6 -112
- package/server/staLogs/staEventTable.callWorker.mjs +11 -0
- package/server/staLogs/staEventTable.mjs +6 -96
- package/server/staLogs/staLogsCore.callWorker.mjs +89 -0
- package/server/staLogs/staLogsCore.mjs +554 -0
- package/server/staLogs/staLogsCore.shellWorker.mjs +28 -0
- package/settings.json +1 -0
- package/src/components/LayoutContentStaInfor.vue +45 -73
- package/tableTags.json +1 -1
- package/dist/css/app.5a2ba039.css +0 -1
- package/logs/2026-06-19T16.log +0 -191
- package/logs/2026-06-19T23.log +0 -0
- package/logs/2026-06-20T00.log +0 -207
- package/logs/2026-06-20T11.log +0 -221
- package/logs/2026-06-20T12.log +0 -146
- package/logs/2026-06-20T13.log +0 -134
- package/logs/2026-06-20T14.log +0 -296
- package/logs/2026-06-20T15.log +0 -225
- package/logs/2026-06-20T16.log +0 -174
- package/logs/2026-06-21T16.log +0 -110
- package/logs/2026-06-21T17.log +0 -301
- package/logs/2026-06-21T18.log +0 -238
- package/logs/2026-06-21T19.log +0 -141
- package/logs/2026-06-21T20.log +0 -99
- package/logs/2026-06-21T21.log +0 -143
- package/logs/2026-06-21T23.log +0 -26
- package/logs/2026-06-22T00.log +0 -33
- package/logs/2026-06-22T08.log +0 -235
- package/logs/2026-06-22T09.log +0 -246
- package/logs/2026-06-22T10.log +0 -301
- package/logs/2026-06-22T11.log +0 -140
- package/logs/2026-06-22T12.log +0 -22
- package/logs/2026-06-22T14.log +0 -44
- package/logs/2026-06-22T23.log +0 -951
- package/logs/2026-06-23T00.log +0 -263
- package/logs/2026-06-23T08.log +0 -611
- package/logs/2026-06-30T21.log +0 -3609
- package/logs/2026-06-30T22.log +0 -3682
- package/logs/2026-06-30T23.log +0 -592
- package/logs/2026-07-01T12.log +0 -0
- package/logs/2026-07-09T22.log +0 -2220
- package/logs/2026-07-09T23.log +0 -1140
- package/logs/2026-07-10T12.log +0 -6
- package/logs/2026-07-10T13.log +0 -351
- package/logs/2026-07-10T16.log +0 -1272
- package/logs/2026-07-10T19.log +0 -6
- package/logs/2026-07-10T20.log +0 -1883
- package/logs/2026-07-10T21.log +0 -3505
- package/logs/2026-07-10T22.log +0 -3395
- package/logs/2026-07-11T00.log +0 -1338
- package/logs/2026-07-11T01.log +0 -2492
- package/logs/2026-07-11T17.log +0 -19
- package/logs/2026-08-25T19.log +0 -4704
- package/logs/2026-08-25T20.log +0 -5144
- package/logs/2026-08-25T21.log +0 -2116
- package/logs/2026-08-26T05.log +0 -1678
- package/logs/2026-08-26T06.log +0 -4561
- package/logs/2026-08-26T07.log +0 -4916
- package/logs/2026-08-26T08.log +0 -260
- package/logs/2026-08-26T09.log +0 -1543
- package/logs/2026-08-26T13.log +0 -2559
- package/logs/2026-08-26T14.log +0 -5526
- package/logs/2026-08-26T15.log +0 -2271
- package/server/staLogs/staEvent.shellWorker.mjs +0 -19
- package/z/344/277/256/346/255/243/350/246/217/345/212/203/346/233/270.md +0 -450
package/docs/WWebPerm.html
CHANGED
|
@@ -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#
|
|
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
|
+
<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
|
+
<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
|
+
<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
|
|
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>
|
package/docs/WWebPerm.mjs.html
CHANGED
|
@@ -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 = './
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
9
|
-
"w-component-vue": "^2.5.
|
|
10
|
-
"w-data-collector": "^1.0.
|
|
11
|
-
"w-echarts-vue": "^1.0.
|
|
12
|
-
"w-serv-hapi": "^1.0.
|
|
13
|
-
"w-serv-orm": "^1.0.
|
|
14
|
-
"w-syslog": "^1.0.
|
|
15
|
-
"w-ui-loginout": "^1.0.
|
|
16
|
-
"wsemi": "^1.8.
|
|
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.
|
|
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.
|
|
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
|
|
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",
|
package/server/WWebPerm.mjs
CHANGED
|
@@ -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 = './
|
|
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
|
package/server/procLang.mjs
CHANGED
|
@@ -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: `全部加總`,
|
package/server/procStaInfor.mjs
CHANGED
|
@@ -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 = './
|
|
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
|
-
|
|
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
|
-
|
|
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 = './
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
16
|
-
//回傳: [{ time, data: { count, <event1>: n, <event2>: m, ... } }, ...]
|
|
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
|
-
|
|
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
|