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

如何在NestJS中优雅地记录Request对象?

解决NestJS Logger打印Request对象显示[object Object]的问题

问题原因

NestJS的@nestjs/common/Logger默认会将传入的消息转为字符串(调用对象的toString()方法),而JavaScript中普通对象的toString()返回值就是[object Object]。相比之下,console.log会自动序列化对象并处理循环引用,因此能正常展示对象详情。

解决方案

1. 手动提取Request关键属性序列化

直接打印整个Request对象会触发循环引用问题(比如req.res指向回req),建议只提取调试所需的核心字段再转为JSON字符串:

控制器修改示例:

@Get()
findAll(@Req() request: Request): string {
  const reqDebugInfo = {
    method: request.method,
    url: request.url,
    query: request.query,
    body: request.body,
    clientIp: request.ip,
    userAgent: request.get('User-Agent')
  };
  this.logger.log(JSON.stringify(reqDebugInfo, null, 2));
  return this.messagesService.findAll();
}

服务修改示例:

findAll(): string {
  const reqDebugInfo = {
    method: this.request.method,
    url: this.request.url,
    query: this.request.query
  };
  this.logger.log(JSON.stringify(reqDebugInfo, null, 2));
  return "all messages";
}

2. 使用Node.js内置util.inspect处理循环引用

Node.js的util.inspect工具可以安全序列化带循环引用的对象,且支持自定义输出格式:

先导入util模块:

import * as util from 'util';

然后在日志中使用:

this.logger.log(util.inspect(request, { 
  depth: null, // 展开所有层级的属性
  colors: false, // 禁用ANSI颜色,避免Logger输出乱码
  compact: false // 格式化换行输出
}));

3. 扩展NestJS Logger实现自动对象序列化

创建自定义Logger类,重写日志方法以自动处理对象类型的消息:

import { Logger } from '@nestjs/common';
import * as util from 'util';

export class ObjectFriendlyLogger extends Logger {
  log(message: any, context?: string) {
    this.processMessage(message, context, 'log');
  }

  error(message: any, trace?: string, context?: string) {
    this.processMessage(message, context, 'error', trace);
  }

  warn(message: any, context?: string) {
    this.processMessage(message, context, 'warn');
  }

  debug(message: any, context?: string) {
    this.processMessage(message, context, 'debug');
  }

  verbose(message: any, context?: string) {
    this.processMessage(message, context, 'verbose');
  }

  private processMessage(message: any, context: string | undefined, level: string, trace?: string) {
    const formattedMsg = typeof message === 'object' 
      ? util.inspect(message, { depth: null, colors: false, compact: false })
      : message;

    switch(level) {
      case 'log': super.log(formattedMsg, context); break;
      case 'error': super.error(formattedMsg, trace, context); break;
      case 'warn': super.warn(formattedMsg, context); break;
      case 'debug': super.debug(formattedMsg, context); break;
      case 'verbose': super.verbose(formattedMsg, context); break;
    }
  }
}

之后在控制器和服务中使用自定义Logger:

private readonly logger = new ObjectFriendlyLogger(MessagesController.name);

内容的提问来源于stack exchange,提问作者Marcus Junius Brutus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:34:54