agora-foundation 3.9.1 → 3.10.0-beta
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/lib/decorator/validate/index.js +0 -3
- package/lib/utilities/tools.d.ts +1 -1
- package/lib/utilities/tools.js +8 -5
- package/lib/utilities/zip.d.ts +4 -0
- package/lib/utilities/zip.js +62 -33
- package/lib/worker/handler/fs-log.js +45 -24
- package/lib/worker/handler/log-rotate-new.js +75 -58
- package/lib/worker/handler/log.js +1 -1
- package/lib-es/decorator/validate/index.js +0 -3
- package/lib-es/utilities/tools.js +8 -5
- package/lib-es/utilities/zip.js +62 -33
- package/lib-es/worker/handler/fs-log.js +45 -24
- package/lib-es/worker/handler/log-rotate-new.js +75 -58
- package/lib-es/worker/handler/log.js +1 -1
- package/package.json +2 -2
|
@@ -11,9 +11,6 @@ require("core-js/modules/es.array.concat.js");
|
|
|
11
11
|
require("core-js/modules/es.array.for-each.js");
|
|
12
12
|
require("core-js/modules/es.function.name.js");
|
|
13
13
|
require("core-js/modules/es.object.to-string.js");
|
|
14
|
-
require("core-js/modules/esnext.iterator.constructor.js");
|
|
15
|
-
require("core-js/modules/esnext.iterator.for-each.js");
|
|
16
|
-
require("core-js/modules/web.dom-collections.for-each.js");
|
|
17
14
|
function validateParams(handlerError) {
|
|
18
15
|
return function () {
|
|
19
16
|
for (var _len = arguments.length, schemas = new Array(_len), _key = 0; _key < _len; _key++) {
|
package/lib/utilities/tools.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export declare const uint8ArrayToImageData: (target: {
|
|
|
22
22
|
buffer?: Uint8Array;
|
|
23
23
|
width?: number;
|
|
24
24
|
height?: number;
|
|
25
|
-
|
|
25
|
+
needsColorSwap: boolean;
|
|
26
26
|
}) => string;
|
|
27
27
|
export declare const renderMeetingId: (meetingId: string | undefined, roomId: string) => string;
|
|
28
28
|
export {};
|
package/lib/utilities/tools.js
CHANGED
|
@@ -117,14 +117,17 @@ var uint8ArrayToImageData = exports.uint8ArrayToImageData = function uint8ArrayT
|
|
|
117
117
|
var srow = row;
|
|
118
118
|
var imageData = ctx.createImageData(width, 1);
|
|
119
119
|
var start = srow * width * 4;
|
|
120
|
-
if (target.
|
|
120
|
+
if (target.needsColorSwap) {
|
|
121
|
+
// BGRA -> RGBA 转换:交换 B 和 R 通道
|
|
122
|
+
// Windows 和 Linux 平台的 buffer 格式是 BGRA,需要转换为 RGBA
|
|
121
123
|
for (var i = 0; i < rowBytes; i += 4) {
|
|
122
|
-
imageData.data[i] = target.buffer[start + i + 2];
|
|
123
|
-
imageData.data[i + 1] = target.buffer[start + i + 1];
|
|
124
|
-
imageData.data[i + 2] = target.buffer[start + i];
|
|
125
|
-
imageData.data[i + 3] = target.buffer[start + i + 3];
|
|
124
|
+
imageData.data[i] = target.buffer[start + i + 2]; // R
|
|
125
|
+
imageData.data[i + 1] = target.buffer[start + i + 1]; // G
|
|
126
|
+
imageData.data[i + 2] = target.buffer[start + i]; // B
|
|
127
|
+
imageData.data[i + 3] = target.buffer[start + i + 3]; // A
|
|
126
128
|
}
|
|
127
129
|
} else {
|
|
130
|
+
// Mac 平台直接复制(已经是 RGBA 格式)
|
|
128
131
|
for (var _i = 0; _i < rowBytes; ++_i) {
|
|
129
132
|
imageData.data[_i] = target.buffer[start + _i];
|
|
130
133
|
}
|
package/lib/utilities/zip.d.ts
CHANGED
|
@@ -3,16 +3,20 @@ export declare const zipDir: (dirPath: string, options?: {
|
|
|
3
3
|
filePattern?: RegExp;
|
|
4
4
|
dirPattern?: RegExp;
|
|
5
5
|
clean?: boolean;
|
|
6
|
+
fileExtensionPattern?: RegExp;
|
|
7
|
+
zipFileName?: string;
|
|
6
8
|
}) => Promise<File | null>;
|
|
7
9
|
/**
|
|
8
10
|
* 删除目录中不符合规则的旧文件和目录
|
|
9
11
|
* @param dirPath 目录路径
|
|
10
12
|
* @param options.filePattern 文件名匹配规则(不符合的删除)
|
|
11
13
|
* @param options.dirPattern 目录名匹配规则(不符合的删除)
|
|
14
|
+
* @param options.fileExtensionPattern 文件扩展名匹配规则(如 /\.(log|txt)$/),不传则不过滤
|
|
12
15
|
*/
|
|
13
16
|
export declare const cleanDir: (dirPath: string, options?: {
|
|
14
17
|
filePattern?: RegExp;
|
|
15
18
|
dirPattern?: RegExp;
|
|
19
|
+
fileExtensionPattern?: RegExp;
|
|
16
20
|
}) => Promise<void>;
|
|
17
21
|
export declare const createMultiEntryZip: () => {
|
|
18
22
|
addFile: (fileName: string, content: string) => void;
|
package/lib/utilities/zip.js
CHANGED
|
@@ -42,7 +42,7 @@ var COMPRESSION_LEVEL = 9;
|
|
|
42
42
|
var zipDir = exports.zipDir = function zipDir(dirPath, options) {
|
|
43
43
|
return new Promise(/*#__PURE__*/function () {
|
|
44
44
|
var _ref = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2(resolve) {
|
|
45
|
-
var fs, recursive, files, zip, _iterator, _step, _step$value, relativePath, absolutePath, logsStr, blob, buffer, now, datefmt, file, _t2;
|
|
45
|
+
var fs, recursive, files, zip, _iterator, _step, _step$value, relativePath, absolutePath, logsStr, blob, buffer, now, datefmt, fileName, file, _t2;
|
|
46
46
|
return _regenerator["default"].wrap(function (_context2) {
|
|
47
47
|
while (1) switch (_context2.prev = _context2.next) {
|
|
48
48
|
case 0:
|
|
@@ -57,7 +57,8 @@ var zipDir = exports.zipDir = function zipDir(dirPath, options) {
|
|
|
57
57
|
_context2.next = 1;
|
|
58
58
|
return cleanDir(dirPath, {
|
|
59
59
|
filePattern: options.filePattern,
|
|
60
|
-
dirPattern: options.dirPattern
|
|
60
|
+
dirPattern: options.dirPattern,
|
|
61
|
+
fileExtensionPattern: options.fileExtensionPattern
|
|
61
62
|
});
|
|
62
63
|
case 1:
|
|
63
64
|
if (!recursive) {
|
|
@@ -67,7 +68,8 @@ var zipDir = exports.zipDir = function zipDir(dirPath, options) {
|
|
|
67
68
|
_context2.next = 2;
|
|
68
69
|
return _collectFiles(dirPath, {
|
|
69
70
|
filePattern: options === null || options === void 0 ? void 0 : options.filePattern,
|
|
70
|
-
dirPattern: options === null || options === void 0 ? void 0 : options.dirPattern
|
|
71
|
+
dirPattern: options === null || options === void 0 ? void 0 : options.dirPattern,
|
|
72
|
+
fileExtensionPattern: options === null || options === void 0 ? void 0 : options.fileExtensionPattern
|
|
71
73
|
});
|
|
72
74
|
case 2:
|
|
73
75
|
files = _context2.sent;
|
|
@@ -107,7 +109,8 @@ var zipDir = exports.zipDir = function zipDir(dirPath, options) {
|
|
|
107
109
|
buffer = _context2.sent;
|
|
108
110
|
now = new Date();
|
|
109
111
|
datefmt = now.toISOString().replace(/\.\d{3}Z$/, 'Z') + 'Z';
|
|
110
|
-
|
|
112
|
+
fileName = (options === null || options === void 0 ? void 0 : options.zipFileName) || "logs-".concat(datefmt);
|
|
113
|
+
file = new File([buffer], "".concat(fileName, ".zip"), {
|
|
111
114
|
type: 'application/zip'
|
|
112
115
|
});
|
|
113
116
|
resolve(file);
|
|
@@ -117,7 +120,7 @@ var zipDir = exports.zipDir = function zipDir(dirPath, options) {
|
|
|
117
120
|
// 原有逻辑:只处理顶层文件
|
|
118
121
|
fs.readdir(dirPath, /*#__PURE__*/function () {
|
|
119
122
|
var _ref2 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(err, files) {
|
|
120
|
-
var zip, _iterator2, _step2, _file, filePath, _logsStr, blob, buffer, now, datefmt, file, _t;
|
|
123
|
+
var zip, _iterator2, _step2, _file, filePath, _logsStr, blob, buffer, now, datefmt, fileName, file, _t;
|
|
121
124
|
return _regenerator["default"].wrap(function (_context) {
|
|
122
125
|
while (1) switch (_context.prev = _context.next) {
|
|
123
126
|
case 0:
|
|
@@ -142,42 +145,48 @@ var zipDir = exports.zipDir = function zipDir(dirPath, options) {
|
|
|
142
145
|
_iterator2.s();
|
|
143
146
|
case 4:
|
|
144
147
|
if ((_step2 = _iterator2.n()).done) {
|
|
145
|
-
_context.next =
|
|
148
|
+
_context.next = 9;
|
|
146
149
|
break;
|
|
147
150
|
}
|
|
148
151
|
_file = _step2.value;
|
|
149
|
-
if (!(options !== null && options !== void 0 && options.
|
|
152
|
+
if (!(options !== null && options !== void 0 && options.fileExtensionPattern && !options.fileExtensionPattern.test(_file))) {
|
|
150
153
|
_context.next = 5;
|
|
151
154
|
break;
|
|
152
155
|
}
|
|
153
|
-
return _context.abrupt("continue",
|
|
156
|
+
return _context.abrupt("continue", 8);
|
|
154
157
|
case 5:
|
|
158
|
+
if (!(options !== null && options !== void 0 && options.filePattern && !options.filePattern.test(_file))) {
|
|
159
|
+
_context.next = 6;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
return _context.abrupt("continue", 8);
|
|
163
|
+
case 6:
|
|
155
164
|
filePath = "".concat(dirPath, "/").concat(_file);
|
|
156
|
-
_context.next =
|
|
165
|
+
_context.next = 7;
|
|
157
166
|
return isFile(filePath);
|
|
158
|
-
case
|
|
167
|
+
case 7:
|
|
159
168
|
if (!_context.sent) {
|
|
160
|
-
_context.next =
|
|
169
|
+
_context.next = 8;
|
|
161
170
|
break;
|
|
162
171
|
}
|
|
163
172
|
_logsStr = fs.readFileSync(filePath, 'utf8');
|
|
164
173
|
zip.file(_file, _logsStr);
|
|
165
|
-
case 7:
|
|
166
|
-
_context.next = 4;
|
|
167
|
-
break;
|
|
168
174
|
case 8:
|
|
169
|
-
_context.next =
|
|
175
|
+
_context.next = 4;
|
|
170
176
|
break;
|
|
171
177
|
case 9:
|
|
172
|
-
_context.
|
|
173
|
-
|
|
174
|
-
_iterator2.e(_t);
|
|
178
|
+
_context.next = 11;
|
|
179
|
+
break;
|
|
175
180
|
case 10:
|
|
176
181
|
_context.prev = 10;
|
|
177
|
-
|
|
178
|
-
|
|
182
|
+
_t = _context["catch"](3);
|
|
183
|
+
_iterator2.e(_t);
|
|
179
184
|
case 11:
|
|
180
|
-
_context.
|
|
185
|
+
_context.prev = 11;
|
|
186
|
+
_iterator2.f();
|
|
187
|
+
return _context.finish(11);
|
|
188
|
+
case 12:
|
|
189
|
+
_context.next = 13;
|
|
181
190
|
return zip.generateAsync({
|
|
182
191
|
type: 'blob',
|
|
183
192
|
compression: 'DEFLATE',
|
|
@@ -185,23 +194,24 @@ var zipDir = exports.zipDir = function zipDir(dirPath, options) {
|
|
|
185
194
|
level: COMPRESSION_LEVEL
|
|
186
195
|
}
|
|
187
196
|
});
|
|
188
|
-
case
|
|
197
|
+
case 13:
|
|
189
198
|
blob = _context.sent;
|
|
190
|
-
_context.next =
|
|
199
|
+
_context.next = 14;
|
|
191
200
|
return blob.arrayBuffer();
|
|
192
|
-
case
|
|
201
|
+
case 14:
|
|
193
202
|
buffer = _context.sent;
|
|
194
203
|
now = new Date();
|
|
195
204
|
datefmt = now.toISOString().replace(/\.\d{3}Z$/, 'Z') + 'Z';
|
|
196
|
-
|
|
205
|
+
fileName = (options === null || options === void 0 ? void 0 : options.zipFileName) || "logs-".concat(datefmt);
|
|
206
|
+
file = new File([buffer], "".concat(fileName, ".zip"), {
|
|
197
207
|
type: 'application/zip'
|
|
198
208
|
});
|
|
199
209
|
resolve(file);
|
|
200
|
-
case
|
|
210
|
+
case 15:
|
|
201
211
|
case "end":
|
|
202
212
|
return _context.stop();
|
|
203
213
|
}
|
|
204
|
-
}, _callee, null, [[3,
|
|
214
|
+
}, _callee, null, [[3, 10, 11, 12]]);
|
|
205
215
|
}));
|
|
206
216
|
return function (_x2, _x3) {
|
|
207
217
|
return _ref2.apply(this, arguments);
|
|
@@ -286,6 +296,7 @@ var isDirectory = /*#__PURE__*/function () {
|
|
|
286
296
|
* @param dirPath 目录路径
|
|
287
297
|
* @param options.filePattern 文件名匹配规则(不符合的删除)
|
|
288
298
|
* @param options.dirPattern 目录名匹配规则(不符合的删除)
|
|
299
|
+
* @param options.fileExtensionPattern 文件扩展名匹配规则(如 /\.(log|txt)$/),不传则不过滤
|
|
289
300
|
*/
|
|
290
301
|
var cleanDir = exports.cleanDir = function cleanDir(dirPath, options) {
|
|
291
302
|
return new Promise(function (resolve) {
|
|
@@ -295,7 +306,7 @@ var cleanDir = exports.cleanDir = function cleanDir(dirPath, options) {
|
|
|
295
306
|
withFileTypes: true
|
|
296
307
|
}, /*#__PURE__*/function () {
|
|
297
308
|
var _ref5 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee5(err, items) {
|
|
298
|
-
var _iterator3, _step3, item, itemPath, dirMatches, _t3;
|
|
309
|
+
var _iterator3, _step3, item, itemPath, matchesExtension, matchesPattern, keep, dirMatches, _t3;
|
|
299
310
|
return _regenerator["default"].wrap(function (_context5) {
|
|
300
311
|
while (1) switch (_context5.prev = _context5.next) {
|
|
301
312
|
case 0:
|
|
@@ -328,8 +339,11 @@ var cleanDir = exports.cleanDir = function cleanDir(dirPath, options) {
|
|
|
328
339
|
_context5.next = 5;
|
|
329
340
|
break;
|
|
330
341
|
}
|
|
331
|
-
//
|
|
332
|
-
|
|
342
|
+
// 文件:检查扩展名和 filePattern
|
|
343
|
+
matchesExtension = options !== null && options !== void 0 && options.fileExtensionPattern ? options.fileExtensionPattern.test(item.name) : true;
|
|
344
|
+
matchesPattern = options !== null && options !== void 0 && options.filePattern ? options.filePattern.test(item.name) : true;
|
|
345
|
+
keep = matchesExtension && matchesPattern;
|
|
346
|
+
if (!keep) {
|
|
333
347
|
fs.unlinkSync(itemPath);
|
|
334
348
|
console.log("[cleanDir] deleted file: ".concat(itemPath));
|
|
335
349
|
}
|
|
@@ -469,7 +483,12 @@ var _cleanDirRecursively = /*#__PURE__*/function () {
|
|
|
469
483
|
|
|
470
484
|
/**
|
|
471
485
|
* 递归遍历目录并收集所有文件
|
|
472
|
-
*
|
|
486
|
+
* @param dirPath 目录路径
|
|
487
|
+
* @param fileExtensionPattern 文件扩展名匹配规则(对所有目录生效)
|
|
488
|
+
* @param options.filePattern 文件名匹配规则(只对顶层目录生效)
|
|
489
|
+
* @param options.dirPattern 目录名匹配规则
|
|
490
|
+
* @param baseDir 基础目录路径
|
|
491
|
+
* @param skipFileFilter 是否跳过 filePattern 验证(子目录中使用)
|
|
473
492
|
*/
|
|
474
493
|
var _collectFiles = /*#__PURE__*/function () {
|
|
475
494
|
var _ref7 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee7(dirPath, options) {
|
|
@@ -481,6 +500,8 @@ var _collectFiles = /*#__PURE__*/function () {
|
|
|
481
500
|
_iterator5,
|
|
482
501
|
_step5,
|
|
483
502
|
entry,
|
|
503
|
+
patternFail,
|
|
504
|
+
extFail,
|
|
484
505
|
relativePath,
|
|
485
506
|
subFiles,
|
|
486
507
|
_args7 = arguments,
|
|
@@ -527,7 +548,13 @@ var _collectFiles = /*#__PURE__*/function () {
|
|
|
527
548
|
_context7.next = 6;
|
|
528
549
|
break;
|
|
529
550
|
}
|
|
530
|
-
if (
|
|
551
|
+
if (skipFileFilter) {
|
|
552
|
+
_context7.next = 5;
|
|
553
|
+
break;
|
|
554
|
+
}
|
|
555
|
+
patternFail = (options === null || options === void 0 ? void 0 : options.filePattern) && !options.filePattern.test(entry.name);
|
|
556
|
+
extFail = (options === null || options === void 0 ? void 0 : options.fileExtensionPattern) && !options.fileExtensionPattern.test(entry.name);
|
|
557
|
+
if (!(patternFail || extFail)) {
|
|
531
558
|
_context7.next = 5;
|
|
532
559
|
break;
|
|
533
560
|
}
|
|
@@ -555,7 +582,9 @@ var _collectFiles = /*#__PURE__*/function () {
|
|
|
555
582
|
return _context7.abrupt("continue", 10);
|
|
556
583
|
case 8:
|
|
557
584
|
_context7.next = 9;
|
|
558
|
-
return _collectFiles(entry.path,
|
|
585
|
+
return _collectFiles(entry.path, {
|
|
586
|
+
fileExtensionPattern: options === null || options === void 0 ? void 0 : options.fileExtensionPattern
|
|
587
|
+
}, baseDir, false);
|
|
559
588
|
case 9:
|
|
560
589
|
subFiles = _context7.sent;
|
|
561
590
|
result.push.apply(result, (0, _toConsumableArray2["default"])(subFiles));
|
|
@@ -25,6 +25,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
25
25
|
exports.collectLogsOnFs = exports.clearTempLogs = void 0;
|
|
26
26
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
27
27
|
require("core-js/modules/es.array.concat.js");
|
|
28
|
+
require("core-js/modules/es.string.ends-with.js");
|
|
28
29
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
29
30
|
var _jszip = _interopRequireDefault(require("jszip"));
|
|
30
31
|
var _constants = require("../constants");
|
|
@@ -43,7 +44,7 @@ var collectLogsOnFs = exports.collectLogsOnFs = /*#__PURE__*/function () {
|
|
|
43
44
|
fs = window.require('fs');
|
|
44
45
|
fs.readdir(logDirPath, /*#__PURE__*/function () {
|
|
45
46
|
var _ref2 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(err, files) {
|
|
46
|
-
var zip, _iterator, _step, file, filePath, logFileData, blob, buffer;
|
|
47
|
+
var zip, _iterator, _step, file, filePath, logFileData, blob, buffer, _t;
|
|
47
48
|
return _regenerator["default"].wrap(function (_context) {
|
|
48
49
|
while (1) switch (_context.prev = _context.next) {
|
|
49
50
|
case 0:
|
|
@@ -55,7 +56,7 @@ var collectLogsOnFs = exports.collectLogsOnFs = /*#__PURE__*/function () {
|
|
|
55
56
|
(0, _reply.reply)(self, callId, _constants.WorkerDirectives.COLLECT_LOGS_ON_FS, {
|
|
56
57
|
isSuccess: false
|
|
57
58
|
});
|
|
58
|
-
_context.next =
|
|
59
|
+
_context.next = 13;
|
|
59
60
|
break;
|
|
60
61
|
case 1:
|
|
61
62
|
if (!(files.length === 0)) {
|
|
@@ -66,42 +67,62 @@ var collectLogsOnFs = exports.collectLogsOnFs = /*#__PURE__*/function () {
|
|
|
66
67
|
isSuccess: true,
|
|
67
68
|
buffer: null
|
|
68
69
|
});
|
|
69
|
-
_context.next =
|
|
70
|
+
_context.next = 13;
|
|
70
71
|
break;
|
|
71
72
|
case 2:
|
|
72
73
|
zip = new _jszip["default"]();
|
|
73
74
|
_iterator = _createForOfIteratorHelper(files);
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
75
|
+
_context.prev = 3;
|
|
76
|
+
_iterator.s();
|
|
77
|
+
case 4:
|
|
78
|
+
if ((_step = _iterator.n()).done) {
|
|
79
|
+
_context.next = 7;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
file = _step.value;
|
|
83
|
+
if (file.endsWith('.log')) {
|
|
84
|
+
_context.next = 5;
|
|
85
|
+
break;
|
|
85
86
|
}
|
|
86
|
-
_context.
|
|
87
|
+
return _context.abrupt("continue", 6);
|
|
88
|
+
case 5:
|
|
89
|
+
filePath = "".concat(logDirPath, "/").concat(file);
|
|
90
|
+
logFileData = fs.readFileSync(filePath);
|
|
91
|
+
zip.file(file, logFileData);
|
|
92
|
+
case 6:
|
|
93
|
+
_context.next = 4;
|
|
94
|
+
break;
|
|
95
|
+
case 7:
|
|
96
|
+
_context.next = 9;
|
|
97
|
+
break;
|
|
98
|
+
case 8:
|
|
99
|
+
_context.prev = 8;
|
|
100
|
+
_t = _context["catch"](3);
|
|
101
|
+
_iterator.e(_t);
|
|
102
|
+
case 9:
|
|
103
|
+
_context.prev = 9;
|
|
104
|
+
_iterator.f();
|
|
105
|
+
return _context.finish(9);
|
|
106
|
+
case 10:
|
|
107
|
+
_context.next = 11;
|
|
87
108
|
return zip.generateAsync({
|
|
88
109
|
type: 'blob'
|
|
89
110
|
});
|
|
90
|
-
case
|
|
111
|
+
case 11:
|
|
91
112
|
blob = _context.sent;
|
|
92
|
-
_context.next =
|
|
113
|
+
_context.next = 12;
|
|
93
114
|
return blob.arrayBuffer();
|
|
94
|
-
case
|
|
115
|
+
case 12:
|
|
95
116
|
buffer = _context.sent;
|
|
96
117
|
(0, _reply.reply)(self, callId, _constants.WorkerDirectives.COLLECT_LOGS_ON_FS, {
|
|
97
118
|
isSuccess: true,
|
|
98
119
|
buffer: buffer
|
|
99
120
|
});
|
|
100
|
-
case
|
|
121
|
+
case 13:
|
|
101
122
|
case "end":
|
|
102
123
|
return _context.stop();
|
|
103
124
|
}
|
|
104
|
-
}, _callee);
|
|
125
|
+
}, _callee, null, [[3, 8, 9, 10]]);
|
|
105
126
|
}));
|
|
106
127
|
return function (_x4, _x5) {
|
|
107
128
|
return _ref2.apply(this, arguments);
|
|
@@ -109,7 +130,7 @@ var collectLogsOnFs = exports.collectLogsOnFs = /*#__PURE__*/function () {
|
|
|
109
130
|
}());
|
|
110
131
|
} catch (e) {
|
|
111
132
|
console.error("[logger] failed to get buffer.", e);
|
|
112
|
-
(0, _reply.reply)(self, callId, _constants.WorkerDirectives.
|
|
133
|
+
(0, _reply.reply)(self, callId, _constants.WorkerDirectives.COLLECT_LOGS_ON_FS, {
|
|
113
134
|
isSuccess: false
|
|
114
135
|
});
|
|
115
136
|
}
|
|
@@ -125,7 +146,7 @@ var collectLogsOnFs = exports.collectLogsOnFs = /*#__PURE__*/function () {
|
|
|
125
146
|
}();
|
|
126
147
|
var clearTempLogs = exports.clearTempLogs = /*#__PURE__*/function () {
|
|
127
148
|
var _ref3 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee3(self, callId) {
|
|
128
|
-
var
|
|
149
|
+
var _t2;
|
|
129
150
|
return _regenerator["default"].wrap(function (_context3) {
|
|
130
151
|
while (1) switch (_context3.prev = _context3.next) {
|
|
131
152
|
case 0:
|
|
@@ -140,8 +161,8 @@ var clearTempLogs = exports.clearTempLogs = /*#__PURE__*/function () {
|
|
|
140
161
|
break;
|
|
141
162
|
case 2:
|
|
142
163
|
_context3.prev = 2;
|
|
143
|
-
|
|
144
|
-
console.error("[logger] failed to clear temp logs.",
|
|
164
|
+
_t2 = _context3["catch"](0);
|
|
165
|
+
console.error("[logger] failed to clear temp logs.", _t2);
|
|
145
166
|
(0, _reply.reply)(self, callId, _constants.WorkerDirectives.CLEAR_TEMP_LOGS, {
|
|
146
167
|
isSuccess: false
|
|
147
168
|
});
|
|
@@ -21,6 +21,7 @@ require("core-js/modules/es.array.map.js");
|
|
|
21
21
|
require("core-js/modules/es.array.push.js");
|
|
22
22
|
require("core-js/modules/es.array.slice.js");
|
|
23
23
|
require("core-js/modules/es.array.sort.js");
|
|
24
|
+
require("core-js/modules/es.array.splice.js");
|
|
24
25
|
require("core-js/modules/es.date.to-string.js");
|
|
25
26
|
require("core-js/modules/es.object.to-string.js");
|
|
26
27
|
require("core-js/modules/es.string.ends-with.js");
|
|
@@ -70,10 +71,6 @@ var createRotateTransport = exports.createRotateTransport = function createRotat
|
|
|
70
71
|
_this.path = require('path');
|
|
71
72
|
return _this;
|
|
72
73
|
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* 生成唯一的日志文件名,避免同一秒多次轮转导致的覆盖
|
|
76
|
-
*/
|
|
77
74
|
(0, _inherits2["default"])(CustomRotateTransport, _WinstonTransport);
|
|
78
75
|
return (0, _createClass2["default"])(CustomRotateTransport, [{
|
|
79
76
|
key: "generateLogFilename",
|
|
@@ -87,10 +84,6 @@ var createRotateTransport = exports.createRotateTransport = function createRotat
|
|
|
87
84
|
}
|
|
88
85
|
return this.rotateIndex === 0 ? "".concat(this.filenamePrefix, "-").concat(timestamp, ".log") : "".concat(this.filenamePrefix, "-").concat(timestamp, "-").concat(this.rotateIndex, ".log");
|
|
89
86
|
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* 创建新日志文件,并清理旧文件
|
|
93
|
-
*/
|
|
94
87
|
}, {
|
|
95
88
|
key: "createNewLogFile",
|
|
96
89
|
value: function createNewLogFile() {
|
|
@@ -109,11 +102,15 @@ var createRotateTransport = exports.createRotateTransport = function createRotat
|
|
|
109
102
|
this.currentStream = this.fs.createWriteStream(this.currentFile, {
|
|
110
103
|
flags: 'a'
|
|
111
104
|
});
|
|
112
|
-
|
|
105
|
+
// 新文件必然从 0 开始,用内存计数器替代 statSync
|
|
106
|
+
this.currentSize = 0;
|
|
107
|
+
this.cleanupOldFiles(this.maxFiles - 1);
|
|
113
108
|
}
|
|
114
109
|
|
|
115
110
|
/**
|
|
116
|
-
*
|
|
111
|
+
* 与老版本结构完全一致,只做一处改动:
|
|
112
|
+
* 原来在写入回调里用 statSync 读磁盘更新 currentSize,
|
|
113
|
+
* 改为用内存计数器 currentSize += buffer.length,消除每条日志的磁盘读操作。
|
|
117
114
|
*/
|
|
118
115
|
}, {
|
|
119
116
|
key: "processQueue",
|
|
@@ -125,86 +122,91 @@ var createRotateTransport = exports.createRotateTransport = function createRotat
|
|
|
125
122
|
buffer = _ref.buffer,
|
|
126
123
|
callback = _ref.callback;
|
|
127
124
|
|
|
128
|
-
// 1. 单条日志大于 maxSize
|
|
125
|
+
// 1. 单条日志大于 maxSize,直接新建新文件并写入
|
|
129
126
|
if (buffer.length > this.maxSize) {
|
|
130
127
|
this.createNewLogFile();
|
|
131
128
|
console.log("[CustomRotateTransport] buffer.length (".concat(buffer.length, ") > maxSize (").concat(this.maxSize, "), force rotate."));
|
|
132
129
|
this.currentStream.write(buffer, function () {
|
|
133
|
-
|
|
134
|
-
_this2.currentSize = _this2.fs.statSync(_this2.currentFile).size;
|
|
135
|
-
} catch (_unused) {
|
|
136
|
-
_this2.currentSize += buffer.length;
|
|
137
|
-
}
|
|
130
|
+
_this2.currentSize += buffer.length; // ← 替代 statSync
|
|
138
131
|
callback();
|
|
139
132
|
_this2.writing = false;
|
|
140
133
|
_this2.processQueue();
|
|
141
|
-
_this2.cleanupOldFiles();
|
|
142
134
|
});
|
|
143
135
|
return;
|
|
144
136
|
}
|
|
145
137
|
|
|
146
|
-
// 2. buffer.length <= maxSize
|
|
138
|
+
// 2. buffer.length <= maxSize,判断 currentStream 是否为空
|
|
147
139
|
if (!this.currentStream) {
|
|
148
140
|
this.createNewLogFile();
|
|
149
141
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
} catch (_unused2) {
|
|
154
|
-
actualSize = this.currentSize;
|
|
155
|
-
}
|
|
156
|
-
if (actualSize + buffer.length > this.maxSize) {
|
|
157
|
-
console.log("[CustomRotateTransport] actualSize (".concat(actualSize, ") + buffer.length (").concat(buffer.length, ") > maxSize (").concat(this.maxSize, "), rotate."));
|
|
142
|
+
|
|
143
|
+
// 用内存计数器替代 existsSync + statSync 判断是否需要轮转
|
|
144
|
+
if (this.currentSize + buffer.length > this.maxSize) {
|
|
158
145
|
this.createNewLogFile();
|
|
159
146
|
}
|
|
160
147
|
this.currentStream.write(buffer, function () {
|
|
161
|
-
|
|
162
|
-
_this2.currentSize = _this2.fs.statSync(_this2.currentFile).size;
|
|
163
|
-
} catch (_unused3) {
|
|
164
|
-
_this2.currentSize += buffer.length;
|
|
165
|
-
}
|
|
148
|
+
_this2.currentSize += buffer.length;
|
|
166
149
|
callback();
|
|
167
150
|
_this2.writing = false;
|
|
168
151
|
_this2.processQueue();
|
|
169
|
-
_this2.cleanupOldFiles();
|
|
170
152
|
});
|
|
171
153
|
}
|
|
172
154
|
|
|
173
155
|
/**
|
|
174
|
-
*
|
|
156
|
+
* 只把同步 I/O(readdirSync / statSync / unlinkSync)改为异步回调,
|
|
157
|
+
* 避免阻塞 Worker 线程导致写入队列积压。
|
|
175
158
|
*/
|
|
176
159
|
}, {
|
|
177
160
|
key: "cleanupOldFiles",
|
|
178
161
|
value: function cleanupOldFiles() {
|
|
179
162
|
var _this3 = this;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
return
|
|
163
|
+
var keepFiles = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.maxFiles;
|
|
164
|
+
var prefix = this.filenamePrefix;
|
|
165
|
+
var logDir = this.logFolderPath;
|
|
166
|
+
console.log("[CustomRotateTransport] cleanupOldFiles: ".concat(logDir));
|
|
167
|
+
this.fs.readdir(logDir, function (err, entries) {
|
|
168
|
+
if (err) {
|
|
169
|
+
console.warn('[CustomRotateTransport] Error reading log folder:', err);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
var files = entries.filter(function (file) {
|
|
173
|
+
return file.startsWith(prefix) && file.endsWith('.log');
|
|
191
174
|
});
|
|
192
|
-
console.log("[CustomRotateTransport] Found ".concat(files.length, " log files,
|
|
193
|
-
if (files.length
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
175
|
+
console.log("[CustomRotateTransport] Found ".concat(files.length, " log files, maxKeepFiles: ").concat(keepFiles));
|
|
176
|
+
if (files.length <= keepFiles) return;
|
|
177
|
+
|
|
178
|
+
// 并行 stat 取 mtime,全部完成后按时间排序删除最旧的
|
|
179
|
+
var pending = files.length;
|
|
180
|
+
var fileInfos = [];
|
|
181
|
+
files.forEach(function (file) {
|
|
182
|
+
var filePath = _this3.path.join(logDir, file);
|
|
183
|
+
_this3.fs.stat(filePath, function (statErr, stat) {
|
|
184
|
+
if (!statErr) {
|
|
185
|
+
fileInfos.push({
|
|
186
|
+
name: file,
|
|
187
|
+
path: filePath,
|
|
188
|
+
stat: stat
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
pending--;
|
|
192
|
+
if (pending === 0) {
|
|
193
|
+
fileInfos.sort(function (a, b) {
|
|
194
|
+
return b.stat.mtime.getTime() - a.stat.mtime.getTime();
|
|
195
|
+
});
|
|
196
|
+
var filesToDelete = fileInfos.slice(keepFiles);
|
|
197
|
+
filesToDelete.forEach(function (f) {
|
|
198
|
+
_this3.fs.unlink(f.path, function (unlinkErr) {
|
|
199
|
+
if (unlinkErr) {
|
|
200
|
+
console.warn("[CustomRotateTransport] Failed to delete log file: ".concat(f.path), unlinkErr);
|
|
201
|
+
} else {
|
|
202
|
+
console.log("[CustomRotateTransport] Deleted old log file: ".concat(f.path));
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
});
|
|
202
206
|
}
|
|
203
207
|
});
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
console.warn('[CustomRotateTransport] Error cleaning up old log files:', err);
|
|
207
|
-
}
|
|
208
|
+
});
|
|
209
|
+
});
|
|
208
210
|
}
|
|
209
211
|
}, {
|
|
210
212
|
key: "log",
|
|
@@ -224,6 +226,21 @@ var createRotateTransport = exports.createRotateTransport = function createRotat
|
|
|
224
226
|
}, {
|
|
225
227
|
key: "close",
|
|
226
228
|
value: function close() {
|
|
229
|
+
// 同步刷入 writeQueue 中还未写入的日志,防止进程退出时丢失
|
|
230
|
+
var remaining = this.writeQueue.splice(0);
|
|
231
|
+
if (remaining.length > 0 && this.currentFile) {
|
|
232
|
+
try {
|
|
233
|
+
var data = Buffer.concat(remaining.map(function (item) {
|
|
234
|
+
return item.buffer;
|
|
235
|
+
}));
|
|
236
|
+
this.fs.appendFileSync(this.currentFile, data);
|
|
237
|
+
} catch (_unused) {
|
|
238
|
+
// 关闭阶段忽略写入错误
|
|
239
|
+
}
|
|
240
|
+
remaining.forEach(function (item) {
|
|
241
|
+
return item.callback();
|
|
242
|
+
});
|
|
243
|
+
}
|
|
227
244
|
if (this.currentStream) {
|
|
228
245
|
this.currentStream.end();
|
|
229
246
|
this.currentStream = null;
|
|
@@ -151,7 +151,7 @@ var collectLogs = exports.collectLogs = /*#__PURE__*/function () {
|
|
|
151
151
|
return _regenerator["default"].wrap(function (_context3) {
|
|
152
152
|
while (1) switch (_context3.prev = _context3.next) {
|
|
153
153
|
case 0:
|
|
154
|
-
buffer = new ArrayBuffer();
|
|
154
|
+
buffer = new ArrayBuffer(0);
|
|
155
155
|
lastId = 0;
|
|
156
156
|
_context3.prev = 1;
|
|
157
157
|
_createMultiEntryZip = (0, _zip.createMultiEntryZip)(), addFile = _createMultiEntryZip.addFile, finish = _createMultiEntryZip.finish;
|
|
@@ -4,9 +4,6 @@ import "core-js/modules/es.array.concat.js";
|
|
|
4
4
|
import "core-js/modules/es.array.for-each.js";
|
|
5
5
|
import "core-js/modules/es.function.name.js";
|
|
6
6
|
import "core-js/modules/es.object.to-string.js";
|
|
7
|
-
import "core-js/modules/esnext.iterator.constructor.js";
|
|
8
|
-
import "core-js/modules/esnext.iterator.for-each.js";
|
|
9
|
-
import "core-js/modules/web.dom-collections.for-each.js";
|
|
10
7
|
function validateParams(handlerError) {
|
|
11
8
|
return function () {
|
|
12
9
|
for (var _len = arguments.length, schemas = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
@@ -107,14 +107,17 @@ export var uint8ArrayToImageData = function uint8ArrayToImageData(target) {
|
|
|
107
107
|
var srow = row;
|
|
108
108
|
var imageData = ctx.createImageData(width, 1);
|
|
109
109
|
var start = srow * width * 4;
|
|
110
|
-
if (target.
|
|
110
|
+
if (target.needsColorSwap) {
|
|
111
|
+
// BGRA -> RGBA 转换:交换 B 和 R 通道
|
|
112
|
+
// Windows 和 Linux 平台的 buffer 格式是 BGRA,需要转换为 RGBA
|
|
111
113
|
for (var i = 0; i < rowBytes; i += 4) {
|
|
112
|
-
imageData.data[i] = target.buffer[start + i + 2];
|
|
113
|
-
imageData.data[i + 1] = target.buffer[start + i + 1];
|
|
114
|
-
imageData.data[i + 2] = target.buffer[start + i];
|
|
115
|
-
imageData.data[i + 3] = target.buffer[start + i + 3];
|
|
114
|
+
imageData.data[i] = target.buffer[start + i + 2]; // R
|
|
115
|
+
imageData.data[i + 1] = target.buffer[start + i + 1]; // G
|
|
116
|
+
imageData.data[i + 2] = target.buffer[start + i]; // B
|
|
117
|
+
imageData.data[i + 3] = target.buffer[start + i + 3]; // A
|
|
116
118
|
}
|
|
117
119
|
} else {
|
|
120
|
+
// Mac 平台直接复制(已经是 RGBA 格式)
|
|
118
121
|
for (var _i = 0; _i < rowBytes; ++_i) {
|
|
119
122
|
imageData.data[_i] = target.buffer[start + _i];
|
|
120
123
|
}
|
package/lib-es/utilities/zip.js
CHANGED
|
@@ -34,7 +34,7 @@ var COMPRESSION_LEVEL = 9;
|
|
|
34
34
|
export var zipDir = function zipDir(dirPath, options) {
|
|
35
35
|
return new Promise(/*#__PURE__*/function () {
|
|
36
36
|
var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(resolve) {
|
|
37
|
-
var fs, recursive, files, zip, _iterator, _step, _step$value, relativePath, absolutePath, logsStr, blob, buffer, now, datefmt, file, _t2;
|
|
37
|
+
var fs, recursive, files, zip, _iterator, _step, _step$value, relativePath, absolutePath, logsStr, blob, buffer, now, datefmt, fileName, file, _t2;
|
|
38
38
|
return _regeneratorRuntime.wrap(function (_context2) {
|
|
39
39
|
while (1) switch (_context2.prev = _context2.next) {
|
|
40
40
|
case 0:
|
|
@@ -49,7 +49,8 @@ export var zipDir = function zipDir(dirPath, options) {
|
|
|
49
49
|
_context2.next = 1;
|
|
50
50
|
return cleanDir(dirPath, {
|
|
51
51
|
filePattern: options.filePattern,
|
|
52
|
-
dirPattern: options.dirPattern
|
|
52
|
+
dirPattern: options.dirPattern,
|
|
53
|
+
fileExtensionPattern: options.fileExtensionPattern
|
|
53
54
|
});
|
|
54
55
|
case 1:
|
|
55
56
|
if (!recursive) {
|
|
@@ -59,7 +60,8 @@ export var zipDir = function zipDir(dirPath, options) {
|
|
|
59
60
|
_context2.next = 2;
|
|
60
61
|
return _collectFiles(dirPath, {
|
|
61
62
|
filePattern: options === null || options === void 0 ? void 0 : options.filePattern,
|
|
62
|
-
dirPattern: options === null || options === void 0 ? void 0 : options.dirPattern
|
|
63
|
+
dirPattern: options === null || options === void 0 ? void 0 : options.dirPattern,
|
|
64
|
+
fileExtensionPattern: options === null || options === void 0 ? void 0 : options.fileExtensionPattern
|
|
63
65
|
});
|
|
64
66
|
case 2:
|
|
65
67
|
files = _context2.sent;
|
|
@@ -99,7 +101,8 @@ export var zipDir = function zipDir(dirPath, options) {
|
|
|
99
101
|
buffer = _context2.sent;
|
|
100
102
|
now = new Date();
|
|
101
103
|
datefmt = now.toISOString().replace(/\.\d{3}Z$/, 'Z') + 'Z';
|
|
102
|
-
|
|
104
|
+
fileName = (options === null || options === void 0 ? void 0 : options.zipFileName) || "logs-".concat(datefmt);
|
|
105
|
+
file = new File([buffer], "".concat(fileName, ".zip"), {
|
|
103
106
|
type: 'application/zip'
|
|
104
107
|
});
|
|
105
108
|
resolve(file);
|
|
@@ -109,7 +112,7 @@ export var zipDir = function zipDir(dirPath, options) {
|
|
|
109
112
|
// 原有逻辑:只处理顶层文件
|
|
110
113
|
fs.readdir(dirPath, /*#__PURE__*/function () {
|
|
111
114
|
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(err, files) {
|
|
112
|
-
var zip, _iterator2, _step2, _file, filePath, _logsStr, blob, buffer, now, datefmt, file, _t;
|
|
115
|
+
var zip, _iterator2, _step2, _file, filePath, _logsStr, blob, buffer, now, datefmt, fileName, file, _t;
|
|
113
116
|
return _regeneratorRuntime.wrap(function (_context) {
|
|
114
117
|
while (1) switch (_context.prev = _context.next) {
|
|
115
118
|
case 0:
|
|
@@ -134,42 +137,48 @@ export var zipDir = function zipDir(dirPath, options) {
|
|
|
134
137
|
_iterator2.s();
|
|
135
138
|
case 4:
|
|
136
139
|
if ((_step2 = _iterator2.n()).done) {
|
|
137
|
-
_context.next =
|
|
140
|
+
_context.next = 9;
|
|
138
141
|
break;
|
|
139
142
|
}
|
|
140
143
|
_file = _step2.value;
|
|
141
|
-
if (!(options !== null && options !== void 0 && options.
|
|
144
|
+
if (!(options !== null && options !== void 0 && options.fileExtensionPattern && !options.fileExtensionPattern.test(_file))) {
|
|
142
145
|
_context.next = 5;
|
|
143
146
|
break;
|
|
144
147
|
}
|
|
145
|
-
return _context.abrupt("continue",
|
|
148
|
+
return _context.abrupt("continue", 8);
|
|
146
149
|
case 5:
|
|
150
|
+
if (!(options !== null && options !== void 0 && options.filePattern && !options.filePattern.test(_file))) {
|
|
151
|
+
_context.next = 6;
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
return _context.abrupt("continue", 8);
|
|
155
|
+
case 6:
|
|
147
156
|
filePath = "".concat(dirPath, "/").concat(_file);
|
|
148
|
-
_context.next =
|
|
157
|
+
_context.next = 7;
|
|
149
158
|
return isFile(filePath);
|
|
150
|
-
case
|
|
159
|
+
case 7:
|
|
151
160
|
if (!_context.sent) {
|
|
152
|
-
_context.next =
|
|
161
|
+
_context.next = 8;
|
|
153
162
|
break;
|
|
154
163
|
}
|
|
155
164
|
_logsStr = fs.readFileSync(filePath, 'utf8');
|
|
156
165
|
zip.file(_file, _logsStr);
|
|
157
|
-
case 7:
|
|
158
|
-
_context.next = 4;
|
|
159
|
-
break;
|
|
160
166
|
case 8:
|
|
161
|
-
_context.next =
|
|
167
|
+
_context.next = 4;
|
|
162
168
|
break;
|
|
163
169
|
case 9:
|
|
164
|
-
_context.
|
|
165
|
-
|
|
166
|
-
_iterator2.e(_t);
|
|
170
|
+
_context.next = 11;
|
|
171
|
+
break;
|
|
167
172
|
case 10:
|
|
168
173
|
_context.prev = 10;
|
|
169
|
-
|
|
170
|
-
|
|
174
|
+
_t = _context["catch"](3);
|
|
175
|
+
_iterator2.e(_t);
|
|
171
176
|
case 11:
|
|
172
|
-
_context.
|
|
177
|
+
_context.prev = 11;
|
|
178
|
+
_iterator2.f();
|
|
179
|
+
return _context.finish(11);
|
|
180
|
+
case 12:
|
|
181
|
+
_context.next = 13;
|
|
173
182
|
return zip.generateAsync({
|
|
174
183
|
type: 'blob',
|
|
175
184
|
compression: 'DEFLATE',
|
|
@@ -177,23 +186,24 @@ export var zipDir = function zipDir(dirPath, options) {
|
|
|
177
186
|
level: COMPRESSION_LEVEL
|
|
178
187
|
}
|
|
179
188
|
});
|
|
180
|
-
case
|
|
189
|
+
case 13:
|
|
181
190
|
blob = _context.sent;
|
|
182
|
-
_context.next =
|
|
191
|
+
_context.next = 14;
|
|
183
192
|
return blob.arrayBuffer();
|
|
184
|
-
case
|
|
193
|
+
case 14:
|
|
185
194
|
buffer = _context.sent;
|
|
186
195
|
now = new Date();
|
|
187
196
|
datefmt = now.toISOString().replace(/\.\d{3}Z$/, 'Z') + 'Z';
|
|
188
|
-
|
|
197
|
+
fileName = (options === null || options === void 0 ? void 0 : options.zipFileName) || "logs-".concat(datefmt);
|
|
198
|
+
file = new File([buffer], "".concat(fileName, ".zip"), {
|
|
189
199
|
type: 'application/zip'
|
|
190
200
|
});
|
|
191
201
|
resolve(file);
|
|
192
|
-
case
|
|
202
|
+
case 15:
|
|
193
203
|
case "end":
|
|
194
204
|
return _context.stop();
|
|
195
205
|
}
|
|
196
|
-
}, _callee, null, [[3,
|
|
206
|
+
}, _callee, null, [[3, 10, 11, 12]]);
|
|
197
207
|
}));
|
|
198
208
|
return function (_x2, _x3) {
|
|
199
209
|
return _ref2.apply(this, arguments);
|
|
@@ -278,6 +288,7 @@ var isDirectory = /*#__PURE__*/function () {
|
|
|
278
288
|
* @param dirPath 目录路径
|
|
279
289
|
* @param options.filePattern 文件名匹配规则(不符合的删除)
|
|
280
290
|
* @param options.dirPattern 目录名匹配规则(不符合的删除)
|
|
291
|
+
* @param options.fileExtensionPattern 文件扩展名匹配规则(如 /\.(log|txt)$/),不传则不过滤
|
|
281
292
|
*/
|
|
282
293
|
export var cleanDir = function cleanDir(dirPath, options) {
|
|
283
294
|
return new Promise(function (resolve) {
|
|
@@ -287,7 +298,7 @@ export var cleanDir = function cleanDir(dirPath, options) {
|
|
|
287
298
|
withFileTypes: true
|
|
288
299
|
}, /*#__PURE__*/function () {
|
|
289
300
|
var _ref5 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5(err, items) {
|
|
290
|
-
var _iterator3, _step3, item, itemPath, dirMatches, _t3;
|
|
301
|
+
var _iterator3, _step3, item, itemPath, matchesExtension, matchesPattern, keep, dirMatches, _t3;
|
|
291
302
|
return _regeneratorRuntime.wrap(function (_context5) {
|
|
292
303
|
while (1) switch (_context5.prev = _context5.next) {
|
|
293
304
|
case 0:
|
|
@@ -320,8 +331,11 @@ export var cleanDir = function cleanDir(dirPath, options) {
|
|
|
320
331
|
_context5.next = 5;
|
|
321
332
|
break;
|
|
322
333
|
}
|
|
323
|
-
//
|
|
324
|
-
|
|
334
|
+
// 文件:检查扩展名和 filePattern
|
|
335
|
+
matchesExtension = options !== null && options !== void 0 && options.fileExtensionPattern ? options.fileExtensionPattern.test(item.name) : true;
|
|
336
|
+
matchesPattern = options !== null && options !== void 0 && options.filePattern ? options.filePattern.test(item.name) : true;
|
|
337
|
+
keep = matchesExtension && matchesPattern;
|
|
338
|
+
if (!keep) {
|
|
325
339
|
fs.unlinkSync(itemPath);
|
|
326
340
|
console.log("[cleanDir] deleted file: ".concat(itemPath));
|
|
327
341
|
}
|
|
@@ -461,7 +475,12 @@ var _cleanDirRecursively = /*#__PURE__*/function () {
|
|
|
461
475
|
|
|
462
476
|
/**
|
|
463
477
|
* 递归遍历目录并收集所有文件
|
|
464
|
-
*
|
|
478
|
+
* @param dirPath 目录路径
|
|
479
|
+
* @param fileExtensionPattern 文件扩展名匹配规则(对所有目录生效)
|
|
480
|
+
* @param options.filePattern 文件名匹配规则(只对顶层目录生效)
|
|
481
|
+
* @param options.dirPattern 目录名匹配规则
|
|
482
|
+
* @param baseDir 基础目录路径
|
|
483
|
+
* @param skipFileFilter 是否跳过 filePattern 验证(子目录中使用)
|
|
465
484
|
*/
|
|
466
485
|
var _collectFiles = /*#__PURE__*/function () {
|
|
467
486
|
var _ref7 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee7(dirPath, options) {
|
|
@@ -473,6 +492,8 @@ var _collectFiles = /*#__PURE__*/function () {
|
|
|
473
492
|
_iterator5,
|
|
474
493
|
_step5,
|
|
475
494
|
entry,
|
|
495
|
+
patternFail,
|
|
496
|
+
extFail,
|
|
476
497
|
relativePath,
|
|
477
498
|
subFiles,
|
|
478
499
|
_args7 = arguments,
|
|
@@ -519,7 +540,13 @@ var _collectFiles = /*#__PURE__*/function () {
|
|
|
519
540
|
_context7.next = 6;
|
|
520
541
|
break;
|
|
521
542
|
}
|
|
522
|
-
if (
|
|
543
|
+
if (skipFileFilter) {
|
|
544
|
+
_context7.next = 5;
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
patternFail = (options === null || options === void 0 ? void 0 : options.filePattern) && !options.filePattern.test(entry.name);
|
|
548
|
+
extFail = (options === null || options === void 0 ? void 0 : options.fileExtensionPattern) && !options.fileExtensionPattern.test(entry.name);
|
|
549
|
+
if (!(patternFail || extFail)) {
|
|
523
550
|
_context7.next = 5;
|
|
524
551
|
break;
|
|
525
552
|
}
|
|
@@ -547,7 +574,9 @@ var _collectFiles = /*#__PURE__*/function () {
|
|
|
547
574
|
return _context7.abrupt("continue", 10);
|
|
548
575
|
case 8:
|
|
549
576
|
_context7.next = 9;
|
|
550
|
-
return _collectFiles(entry.path,
|
|
577
|
+
return _collectFiles(entry.path, {
|
|
578
|
+
fileExtensionPattern: options === null || options === void 0 ? void 0 : options.fileExtensionPattern
|
|
579
|
+
}, baseDir, false);
|
|
551
580
|
case 9:
|
|
552
581
|
subFiles = _context7.sent;
|
|
553
582
|
result.push.apply(result, _toConsumableArray(subFiles));
|
|
@@ -18,6 +18,7 @@ import "core-js/modules/web.dom-collections.iterator.js";
|
|
|
18
18
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
19
19
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
20
20
|
import "core-js/modules/es.array.concat.js";
|
|
21
|
+
import "core-js/modules/es.string.ends-with.js";
|
|
21
22
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
22
23
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
23
24
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
@@ -35,7 +36,7 @@ export var collectLogsOnFs = /*#__PURE__*/function () {
|
|
|
35
36
|
fs = window.require('fs');
|
|
36
37
|
fs.readdir(logDirPath, /*#__PURE__*/function () {
|
|
37
38
|
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(err, files) {
|
|
38
|
-
var zip, _iterator, _step, file, filePath, logFileData, blob, buffer;
|
|
39
|
+
var zip, _iterator, _step, file, filePath, logFileData, blob, buffer, _t;
|
|
39
40
|
return _regeneratorRuntime.wrap(function (_context) {
|
|
40
41
|
while (1) switch (_context.prev = _context.next) {
|
|
41
42
|
case 0:
|
|
@@ -47,7 +48,7 @@ export var collectLogsOnFs = /*#__PURE__*/function () {
|
|
|
47
48
|
reply(self, callId, WorkerDirectives.COLLECT_LOGS_ON_FS, {
|
|
48
49
|
isSuccess: false
|
|
49
50
|
});
|
|
50
|
-
_context.next =
|
|
51
|
+
_context.next = 13;
|
|
51
52
|
break;
|
|
52
53
|
case 1:
|
|
53
54
|
if (!(files.length === 0)) {
|
|
@@ -58,42 +59,62 @@ export var collectLogsOnFs = /*#__PURE__*/function () {
|
|
|
58
59
|
isSuccess: true,
|
|
59
60
|
buffer: null
|
|
60
61
|
});
|
|
61
|
-
_context.next =
|
|
62
|
+
_context.next = 13;
|
|
62
63
|
break;
|
|
63
64
|
case 2:
|
|
64
65
|
zip = new JSZip();
|
|
65
66
|
_iterator = _createForOfIteratorHelper(files);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
_context.prev = 3;
|
|
68
|
+
_iterator.s();
|
|
69
|
+
case 4:
|
|
70
|
+
if ((_step = _iterator.n()).done) {
|
|
71
|
+
_context.next = 7;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
file = _step.value;
|
|
75
|
+
if (file.endsWith('.log')) {
|
|
76
|
+
_context.next = 5;
|
|
77
|
+
break;
|
|
77
78
|
}
|
|
78
|
-
_context.
|
|
79
|
+
return _context.abrupt("continue", 6);
|
|
80
|
+
case 5:
|
|
81
|
+
filePath = "".concat(logDirPath, "/").concat(file);
|
|
82
|
+
logFileData = fs.readFileSync(filePath);
|
|
83
|
+
zip.file(file, logFileData);
|
|
84
|
+
case 6:
|
|
85
|
+
_context.next = 4;
|
|
86
|
+
break;
|
|
87
|
+
case 7:
|
|
88
|
+
_context.next = 9;
|
|
89
|
+
break;
|
|
90
|
+
case 8:
|
|
91
|
+
_context.prev = 8;
|
|
92
|
+
_t = _context["catch"](3);
|
|
93
|
+
_iterator.e(_t);
|
|
94
|
+
case 9:
|
|
95
|
+
_context.prev = 9;
|
|
96
|
+
_iterator.f();
|
|
97
|
+
return _context.finish(9);
|
|
98
|
+
case 10:
|
|
99
|
+
_context.next = 11;
|
|
79
100
|
return zip.generateAsync({
|
|
80
101
|
type: 'blob'
|
|
81
102
|
});
|
|
82
|
-
case
|
|
103
|
+
case 11:
|
|
83
104
|
blob = _context.sent;
|
|
84
|
-
_context.next =
|
|
105
|
+
_context.next = 12;
|
|
85
106
|
return blob.arrayBuffer();
|
|
86
|
-
case
|
|
107
|
+
case 12:
|
|
87
108
|
buffer = _context.sent;
|
|
88
109
|
reply(self, callId, WorkerDirectives.COLLECT_LOGS_ON_FS, {
|
|
89
110
|
isSuccess: true,
|
|
90
111
|
buffer: buffer
|
|
91
112
|
});
|
|
92
|
-
case
|
|
113
|
+
case 13:
|
|
93
114
|
case "end":
|
|
94
115
|
return _context.stop();
|
|
95
116
|
}
|
|
96
|
-
}, _callee);
|
|
117
|
+
}, _callee, null, [[3, 8, 9, 10]]);
|
|
97
118
|
}));
|
|
98
119
|
return function (_x4, _x5) {
|
|
99
120
|
return _ref2.apply(this, arguments);
|
|
@@ -101,7 +122,7 @@ export var collectLogsOnFs = /*#__PURE__*/function () {
|
|
|
101
122
|
}());
|
|
102
123
|
} catch (e) {
|
|
103
124
|
console.error("[logger] failed to get buffer.", e);
|
|
104
|
-
reply(self, callId, WorkerDirectives.
|
|
125
|
+
reply(self, callId, WorkerDirectives.COLLECT_LOGS_ON_FS, {
|
|
105
126
|
isSuccess: false
|
|
106
127
|
});
|
|
107
128
|
}
|
|
@@ -117,7 +138,7 @@ export var collectLogsOnFs = /*#__PURE__*/function () {
|
|
|
117
138
|
}();
|
|
118
139
|
export var clearTempLogs = /*#__PURE__*/function () {
|
|
119
140
|
var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(self, callId) {
|
|
120
|
-
var
|
|
141
|
+
var _t2;
|
|
121
142
|
return _regeneratorRuntime.wrap(function (_context3) {
|
|
122
143
|
while (1) switch (_context3.prev = _context3.next) {
|
|
123
144
|
case 0:
|
|
@@ -132,8 +153,8 @@ export var clearTempLogs = /*#__PURE__*/function () {
|
|
|
132
153
|
break;
|
|
133
154
|
case 2:
|
|
134
155
|
_context3.prev = 2;
|
|
135
|
-
|
|
136
|
-
console.error("[logger] failed to clear temp logs.",
|
|
156
|
+
_t2 = _context3["catch"](0);
|
|
157
|
+
console.error("[logger] failed to clear temp logs.", _t2);
|
|
137
158
|
reply(self, callId, WorkerDirectives.CLEAR_TEMP_LOGS, {
|
|
138
159
|
isSuccess: false
|
|
139
160
|
});
|
|
@@ -14,6 +14,7 @@ import "core-js/modules/es.array.map.js";
|
|
|
14
14
|
import "core-js/modules/es.array.push.js";
|
|
15
15
|
import "core-js/modules/es.array.slice.js";
|
|
16
16
|
import "core-js/modules/es.array.sort.js";
|
|
17
|
+
import "core-js/modules/es.array.splice.js";
|
|
17
18
|
import "core-js/modules/es.date.to-string.js";
|
|
18
19
|
import "core-js/modules/es.object.to-string.js";
|
|
19
20
|
import "core-js/modules/es.string.ends-with.js";
|
|
@@ -62,10 +63,6 @@ export var createRotateTransport = function createRotateTransport(filenamePrefix
|
|
|
62
63
|
_this.path = require('path');
|
|
63
64
|
return _this;
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* 生成唯一的日志文件名,避免同一秒多次轮转导致的覆盖
|
|
68
|
-
*/
|
|
69
66
|
_inherits(CustomRotateTransport, _WinstonTransport);
|
|
70
67
|
return _createClass(CustomRotateTransport, [{
|
|
71
68
|
key: "generateLogFilename",
|
|
@@ -79,10 +76,6 @@ export var createRotateTransport = function createRotateTransport(filenamePrefix
|
|
|
79
76
|
}
|
|
80
77
|
return this.rotateIndex === 0 ? "".concat(this.filenamePrefix, "-").concat(timestamp, ".log") : "".concat(this.filenamePrefix, "-").concat(timestamp, "-").concat(this.rotateIndex, ".log");
|
|
81
78
|
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* 创建新日志文件,并清理旧文件
|
|
85
|
-
*/
|
|
86
79
|
}, {
|
|
87
80
|
key: "createNewLogFile",
|
|
88
81
|
value: function createNewLogFile() {
|
|
@@ -101,11 +94,15 @@ export var createRotateTransport = function createRotateTransport(filenamePrefix
|
|
|
101
94
|
this.currentStream = this.fs.createWriteStream(this.currentFile, {
|
|
102
95
|
flags: 'a'
|
|
103
96
|
});
|
|
104
|
-
|
|
97
|
+
// 新文件必然从 0 开始,用内存计数器替代 statSync
|
|
98
|
+
this.currentSize = 0;
|
|
99
|
+
this.cleanupOldFiles(this.maxFiles - 1);
|
|
105
100
|
}
|
|
106
101
|
|
|
107
102
|
/**
|
|
108
|
-
*
|
|
103
|
+
* 与老版本结构完全一致,只做一处改动:
|
|
104
|
+
* 原来在写入回调里用 statSync 读磁盘更新 currentSize,
|
|
105
|
+
* 改为用内存计数器 currentSize += buffer.length,消除每条日志的磁盘读操作。
|
|
109
106
|
*/
|
|
110
107
|
}, {
|
|
111
108
|
key: "processQueue",
|
|
@@ -117,86 +114,91 @@ export var createRotateTransport = function createRotateTransport(filenamePrefix
|
|
|
117
114
|
buffer = _ref.buffer,
|
|
118
115
|
callback = _ref.callback;
|
|
119
116
|
|
|
120
|
-
// 1. 单条日志大于 maxSize
|
|
117
|
+
// 1. 单条日志大于 maxSize,直接新建新文件并写入
|
|
121
118
|
if (buffer.length > this.maxSize) {
|
|
122
119
|
this.createNewLogFile();
|
|
123
120
|
console.log("[CustomRotateTransport] buffer.length (".concat(buffer.length, ") > maxSize (").concat(this.maxSize, "), force rotate."));
|
|
124
121
|
this.currentStream.write(buffer, function () {
|
|
125
|
-
|
|
126
|
-
_this2.currentSize = _this2.fs.statSync(_this2.currentFile).size;
|
|
127
|
-
} catch (_unused) {
|
|
128
|
-
_this2.currentSize += buffer.length;
|
|
129
|
-
}
|
|
122
|
+
_this2.currentSize += buffer.length; // ← 替代 statSync
|
|
130
123
|
callback();
|
|
131
124
|
_this2.writing = false;
|
|
132
125
|
_this2.processQueue();
|
|
133
|
-
_this2.cleanupOldFiles();
|
|
134
126
|
});
|
|
135
127
|
return;
|
|
136
128
|
}
|
|
137
129
|
|
|
138
|
-
// 2. buffer.length <= maxSize
|
|
130
|
+
// 2. buffer.length <= maxSize,判断 currentStream 是否为空
|
|
139
131
|
if (!this.currentStream) {
|
|
140
132
|
this.createNewLogFile();
|
|
141
133
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
} catch (_unused2) {
|
|
146
|
-
actualSize = this.currentSize;
|
|
147
|
-
}
|
|
148
|
-
if (actualSize + buffer.length > this.maxSize) {
|
|
149
|
-
console.log("[CustomRotateTransport] actualSize (".concat(actualSize, ") + buffer.length (").concat(buffer.length, ") > maxSize (").concat(this.maxSize, "), rotate."));
|
|
134
|
+
|
|
135
|
+
// 用内存计数器替代 existsSync + statSync 判断是否需要轮转
|
|
136
|
+
if (this.currentSize + buffer.length > this.maxSize) {
|
|
150
137
|
this.createNewLogFile();
|
|
151
138
|
}
|
|
152
139
|
this.currentStream.write(buffer, function () {
|
|
153
|
-
|
|
154
|
-
_this2.currentSize = _this2.fs.statSync(_this2.currentFile).size;
|
|
155
|
-
} catch (_unused3) {
|
|
156
|
-
_this2.currentSize += buffer.length;
|
|
157
|
-
}
|
|
140
|
+
_this2.currentSize += buffer.length;
|
|
158
141
|
callback();
|
|
159
142
|
_this2.writing = false;
|
|
160
143
|
_this2.processQueue();
|
|
161
|
-
_this2.cleanupOldFiles();
|
|
162
144
|
});
|
|
163
145
|
}
|
|
164
146
|
|
|
165
147
|
/**
|
|
166
|
-
*
|
|
148
|
+
* 只把同步 I/O(readdirSync / statSync / unlinkSync)改为异步回调,
|
|
149
|
+
* 避免阻塞 Worker 线程导致写入队列积压。
|
|
167
150
|
*/
|
|
168
151
|
}, {
|
|
169
152
|
key: "cleanupOldFiles",
|
|
170
153
|
value: function cleanupOldFiles() {
|
|
171
154
|
var _this3 = this;
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
return
|
|
155
|
+
var keepFiles = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.maxFiles;
|
|
156
|
+
var prefix = this.filenamePrefix;
|
|
157
|
+
var logDir = this.logFolderPath;
|
|
158
|
+
console.log("[CustomRotateTransport] cleanupOldFiles: ".concat(logDir));
|
|
159
|
+
this.fs.readdir(logDir, function (err, entries) {
|
|
160
|
+
if (err) {
|
|
161
|
+
console.warn('[CustomRotateTransport] Error reading log folder:', err);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
var files = entries.filter(function (file) {
|
|
165
|
+
return file.startsWith(prefix) && file.endsWith('.log');
|
|
183
166
|
});
|
|
184
|
-
console.log("[CustomRotateTransport] Found ".concat(files.length, " log files,
|
|
185
|
-
if (files.length
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
167
|
+
console.log("[CustomRotateTransport] Found ".concat(files.length, " log files, maxKeepFiles: ").concat(keepFiles));
|
|
168
|
+
if (files.length <= keepFiles) return;
|
|
169
|
+
|
|
170
|
+
// 并行 stat 取 mtime,全部完成后按时间排序删除最旧的
|
|
171
|
+
var pending = files.length;
|
|
172
|
+
var fileInfos = [];
|
|
173
|
+
files.forEach(function (file) {
|
|
174
|
+
var filePath = _this3.path.join(logDir, file);
|
|
175
|
+
_this3.fs.stat(filePath, function (statErr, stat) {
|
|
176
|
+
if (!statErr) {
|
|
177
|
+
fileInfos.push({
|
|
178
|
+
name: file,
|
|
179
|
+
path: filePath,
|
|
180
|
+
stat: stat
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
pending--;
|
|
184
|
+
if (pending === 0) {
|
|
185
|
+
fileInfos.sort(function (a, b) {
|
|
186
|
+
return b.stat.mtime.getTime() - a.stat.mtime.getTime();
|
|
187
|
+
});
|
|
188
|
+
var filesToDelete = fileInfos.slice(keepFiles);
|
|
189
|
+
filesToDelete.forEach(function (f) {
|
|
190
|
+
_this3.fs.unlink(f.path, function (unlinkErr) {
|
|
191
|
+
if (unlinkErr) {
|
|
192
|
+
console.warn("[CustomRotateTransport] Failed to delete log file: ".concat(f.path), unlinkErr);
|
|
193
|
+
} else {
|
|
194
|
+
console.log("[CustomRotateTransport] Deleted old log file: ".concat(f.path));
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
});
|
|
194
198
|
}
|
|
195
199
|
});
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
console.warn('[CustomRotateTransport] Error cleaning up old log files:', err);
|
|
199
|
-
}
|
|
200
|
+
});
|
|
201
|
+
});
|
|
200
202
|
}
|
|
201
203
|
}, {
|
|
202
204
|
key: "log",
|
|
@@ -216,6 +218,21 @@ export var createRotateTransport = function createRotateTransport(filenamePrefix
|
|
|
216
218
|
}, {
|
|
217
219
|
key: "close",
|
|
218
220
|
value: function close() {
|
|
221
|
+
// 同步刷入 writeQueue 中还未写入的日志,防止进程退出时丢失
|
|
222
|
+
var remaining = this.writeQueue.splice(0);
|
|
223
|
+
if (remaining.length > 0 && this.currentFile) {
|
|
224
|
+
try {
|
|
225
|
+
var data = Buffer.concat(remaining.map(function (item) {
|
|
226
|
+
return item.buffer;
|
|
227
|
+
}));
|
|
228
|
+
this.fs.appendFileSync(this.currentFile, data);
|
|
229
|
+
} catch (_unused) {
|
|
230
|
+
// 关闭阶段忽略写入错误
|
|
231
|
+
}
|
|
232
|
+
remaining.forEach(function (item) {
|
|
233
|
+
return item.callback();
|
|
234
|
+
});
|
|
235
|
+
}
|
|
219
236
|
if (this.currentStream) {
|
|
220
237
|
this.currentStream.end();
|
|
221
238
|
this.currentStream = null;
|
|
@@ -144,7 +144,7 @@ export var collectLogs = /*#__PURE__*/function () {
|
|
|
144
144
|
return _regeneratorRuntime.wrap(function (_context3) {
|
|
145
145
|
while (1) switch (_context3.prev = _context3.next) {
|
|
146
146
|
case 0:
|
|
147
|
-
buffer = new ArrayBuffer();
|
|
147
|
+
buffer = new ArrayBuffer(0);
|
|
148
148
|
lastId = 0;
|
|
149
149
|
_context3.prev = 1;
|
|
150
150
|
_createMultiEntryZip = createMultiEntryZip(), addFile = _createMultiEntryZip.addFile, finish = _createMultiEntryZip.finish;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agora-foundation",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.0-beta",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib-es/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@types/jasmine": "^5.1.4",
|
|
25
25
|
"@types/lodash": "^4.14.168",
|
|
26
26
|
"@types/node": "^20.11.30",
|
|
27
|
-
"agora-toolchain": "3.
|
|
27
|
+
"agora-toolchain": "3.10.0-beta",
|
|
28
28
|
"core-js": "^3.33.3",
|
|
29
29
|
"tslib": "^2.6.2",
|
|
30
30
|
"winston": "^3.16.0",
|