如何将TypeScript+Node项目的stdout/控制台输出同时保存到文件和终端
解决方案
方案1:原生拦截Node.js标准输出流(最稳定,无额外依赖)
所有控制台输出(包括自身代码、第三方模块、子进程输出)最终都会写入process.stdout和process.stderr两个系统流,直接拦截这两个流的写入操作即可实现同时输出到文件和控制台,无需修改现有业务代码和第三方模块逻辑,天然支持跨平台运行。
以下是TypeScript实现代码,直接放在项目入口文件最顶部即可生效:
import * as fs from 'fs'; import * as os from 'os'; // 日志存储路径,Node会自动适配不同系统的路径格式 const FULL_LOG_PATH = './full-output.log'; const ERROR_LOG_PATH = './error-output.log'; // 以追加模式创建写入流,不会覆盖历史日志 const fullLogStream = fs.createWriteStream(FULL_LOG_PATH, { flags: 'a' }); const errorLogStream = fs.createWriteStream(ERROR_LOG_PATH, { flags: 'a' }); // 保存原始写入方法,避免循环调用 const originalStdoutWrite = process.stdout.write.bind(process.stdout); const originalStderrWrite = process.stderr.write.bind(process.stderr); // 拦截普通输出流 process.stdout.write = (chunk: any, encoding?: BufferEncoding, callback?: (error?: Error | null) => void): boolean => { // 同时写入日志文件和原控制台 fullLogStream.write(chunk, encoding); return originalStdoutWrite(chunk, encoding, callback); }; // 拦截错误输出流 process.stderr.write = (chunk: any, encoding?: BufferEncoding, callback?: (error?: Error | null) => void): boolean => { // 错误日志可以单独存储一份,也可以仅存入全量日志 errorLogStream.write(chunk, encoding); fullLogStream.write(chunk, encoding); return originalStderrWrite(chunk, encoding, callback); }; // 进程退出时关闭流,避免日志文件损坏 process.on('exit', () => { fullLogStream.end(); errorLogStream.end(); }); process.on('SIGINT', () => process.exit(0));
该方案优势:
- 无第三方依赖,完全基于Node原生API实现
- 100%捕获所有控制台输出,不存在遗漏
- 天然兼容mac、windows全平台
- 代码入侵性极低,不影响现有业务逻辑
方案2:命令行工具实现(零代码入侵)
如果不想修改项目代码,可以直接通过跨平台命令行工具拦截进程的全部输出,同时写入文件和控制台:
- 先安装跨平台tee工具适配多系统:
npm i cross-tee -D - 修改package.json启动脚本:
{ "scripts": { "start:log": "ts-node src/index.ts | cross-tee full-output.log" } }
如果不想安装额外工具,也可以直接用系统自带命令:
- mac/Linux:
node dist/index.js | tee full-output.log - Windows PowerShell:
node dist/index.js | tee -FilePath full-output.log
注意事项
- 长时间运行的项目可以按日期动态生成日志文件名,实现按天分割日志
- 大流量日志场景可以给写入流增加缓冲区,降低IO频率提升性能
- 生产环境建议配置日志自动清理逻辑,避免日志文件占用过多磁盘空间
内容的提问来源于stack exchange,提问作者MukulCode
相关产品推荐
相关产品推荐

