You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何读取并操作NestJS应用的stdout,过滤指定的knexjs日志提示?

解决方法

方案1:直接从Knex层面关闭警告(更推荐)

你不需要拦截stdout,直接在Knex初始化配置中添加参数即可关闭该特定警告,修改你的Knex连接配置:

import { Knex } from 'knex';

const knexConfig: Knex.Config = {
  client: 'sqlite3',
  connection: {
    filename: './你的数据库文件路径.sqlite3'
  },
  useNullAsDefault: true,
  // 添加以下配置即可关闭returning相关的sqlite警告
  suppressReturningWarning: true
};

如果你是用@nestjs/knex模块,直接将上述配置传入KnexModule.forRoot()的参数即可。

方案2:全局拦截stdout做内容过滤

如果确实需要自定义读取、过滤stdout的所有输出,正确的做法是重写process.stdout.write方法,而不是添加data事件监听器:

  1. 代码必须放在项目入口文件main.ts的最顶部,早于所有模块、Service的初始化逻辑:
// 先保存原始的stdout写入方法
const originalWrite = process.stdout.write.bind(process.stdout);

// 重写写入方法
process.stdout.write = (chunk: any, encoding?: BufferEncoding | ((err?: Error) => void), callback?: (err?: Error) => void) => {
  if (typeof chunk === 'string') {
    // 匹配需要过滤的警告内容
    if (chunk.includes('.returning() is not supported by sqlite3 and will not have any effect.')) {
      // 匹配成功直接跳过输出
      return true;
    }
  }
  // 其余内容正常输出
  return originalWrite(chunk, encoding as BufferEncoding, callback);
};

// 后面才是Nest初始化的原有逻辑
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

原代码失效原因说明

  • process.stdout是可写流,默认不会触发data事件,只有在管道转发场景下才会触发,所以你添加的data监听器根本不会执行。
  • 你在监听器内部调用了console.log,而console.log本身会调用process.stdout.write,会形成死循环导致日志输出卡死,所以会出现没有任何消息输出的问题。
  • 拦截逻辑如果放在Service内部,加载时机晚于Knex初始化的过程,Knex启动阶段的警告已经输出,无法拦截。

内容的提问来源于stack exchange,提问作者Makuna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 22:06:05