diff --git a/packages-serverless/runtime-engine/src/lib/logger.ts b/packages-serverless/runtime-engine/src/lib/logger.ts index e2f5b9e57923..3c63587e59e8 100644 --- a/packages-serverless/runtime-engine/src/lib/logger.ts +++ b/packages-serverless/runtime-engine/src/lib/logger.ts @@ -11,6 +11,7 @@ const debuglog = util.debuglog('RuntimeEngine:Logger'); export class ServerlessLogger extends Logger implements IServerlessLogger { options; + private waiting = false; constructor(options) { super(options); @@ -78,26 +79,44 @@ export class ServerlessLogger extends Logger implements IServerlessLogger { */ protected async rotateLogBySize(): Promise { try { - const maxFileSize = - this.options.maxFileSize || - Number(process.env.LOG_ROTATE_FILE_SIZE) || - DEFAULT_MAX_FILE_SIZE; const transport: any = this.get('file'); if (transport?._stream?.writable) { - const stat = await fs.fstat(transport._stream.fd); - if (stat.size >= maxFileSize) { - this.info( - `File ${transport._stream.path} (fd ${transport._stream.fd}) reach the maximum file size, current size: ${stat.size}, max size: ${maxFileSize}` - ); - await this.rotateBySize(); + if (transport._stream.fd) { + await this.checkAndRotate(transport); + } else { + if (this.waiting) { + debuglog('rotateLogBySize waiting for open fd'); + return; + } + this.waiting = true; + // 如果没有 fd,这里需要监听 open 事件,这时候才会有 fd,否则直接抛异常了 + transport._stream.on('open', async (fd: number) => { + this.waiting = false; + await this.checkAndRotate(transport); + }); } } } catch (e) { + debuglog('rotateLogBySize error =>' + e.stack); e.message = `${e.message}`; this.error(e); } } + protected async checkAndRotate(transport) { + const maxFileSize = + this.options.maxFileSize || + Number(process.env.LOG_ROTATE_FILE_SIZE) || + DEFAULT_MAX_FILE_SIZE; + const stat = await fs.fstat(transport._stream.fd); + if (stat.size >= maxFileSize) { + this.info( + `File ${transport._stream.path} (fd ${transport._stream.fd}) reach the maximum file size, current size: ${stat.size}, max size: ${maxFileSize}` + ); + await this.rotateBySize(); + } + } + /** * Cut log file by size * @param {RotationStrategy} strategy diff --git a/packages-serverless/runtime-engine/test/lib/logger.test.ts b/packages-serverless/runtime-engine/test/lib/logger.test.ts index 4330cb2fd768..693c424439d7 100644 --- a/packages-serverless/runtime-engine/test/lib/logger.test.ts +++ b/packages-serverless/runtime-engine/test/lib/logger.test.ts @@ -114,4 +114,24 @@ describe('logger.test.ts', () => { }); }); }); + + describe('logger benchmark', () => { + it('logger benchmark should be ok', async () => { + const loggerFactory = new BaseLoggerFactory(__dirname); + const log = (loggerFactory as any).createLogger(path.join(__dirname, '_benchmarks/test.log'), { + fileClearInterval: 100, + maxFileSize: 1, + maxFiles: 2, + }); + + for (let i = 0; i < 100000; i++) { + log.info('asjdfaoj230u4u9rpasdjfasjdfpoaiweurpoqwurapsjf;lasdjfopasiefpoqwuerpoajsdpfjasdjfa;lsdjfaosdfjpawierpqoiwe ==> i = %s', i); + log.error('asjdfaoj230u4u9rpasdjfasjdfpoaiweurpoqwurapsjf;lasdjfopasiefpoqwuerpoajsdpfjasdjfa;lsdjfaosdfjpawierpqoiwe ==> i = %s', i); + + // await new Promise(resolve => { + // setTimeout(() => resolve(), 50); + // }); + } + }); + }); });