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

如何配置NestJS日志匹配GCP Stackdriver日志严重级别?

问题根因

NestJS默认输出的是纯文本格式日志,没有遵循GCP Cloud Logging(原Stackdriver)的结构化日志规范携带标准severity字段,GCP无法识别纯文本内容里打印的DEBUG/INFO等级别标识,会默认把所有这类非结构化日志归类为default严重级别,因此按指定verbosity级别筛选时无法匹配到对应日志。

可行配置方案

方案1:使用官方适配的结构化日志库(推荐,无业务代码侵入)

通过替换NestJS默认Logger适配器的方式实现,不需要修改业务中已写的日志调用逻辑:

  1. 安装依赖
    npm install @google-cloud/logging-winston nest-winston winston
    
  2. 在应用入口main.ts中替换默认日志实例:
    import { NestFactory } from '@nestjs/core';
    import { WinstonModule } from 'nest-winston';
    import { LoggingWinston } from '@google-cloud/logging-winston';
    import { AppModule } from './app.module';
    
    async function bootstrap() {
      const gcpLogTransport = new LoggingWinston({
        // 生产环境直接重定向到stdout,Cloud Run环境自动继承服务账号权限,无需手动配置密钥
        redirectToStdout: process.env.NODE_ENV === 'production',
      });
    
      const app = await NestFactory.create(AppModule, {
        logger: WinstonModule.createLogger({
          transports: [gcpLogTransport],
          // 级别映射对齐NestJS原生规则
          levels: {
            error: 0,
            warn: 1,
            log: 2,
            debug: 3,
            verbose: 4,
          },
        }),
      });
    
      await app.listen(process.env.PORT || 3000);
    }
    bootstrap();
    

重新部署到Cloud Run后,输出的日志会自动携带标准severity字段,Logs Explorer的严重级别筛选可直接生效。

方案2:自定义轻量Logger(无额外第三方依赖)

如果不想引入额外日志依赖,可以自行实现符合GCP结构化日志规范的Logger,输出JSON行格式日志即可:

  1. 实现自定义Logger类:
    import { LoggerService, LogLevel } from '@nestjs/common';
    
    const GCP_SEVERITY_MAP: Record<LogLevel, string> = {
      error: 'ERROR',
      warn: 'WARNING',
      log: 'INFO',
      debug: 'DEBUG',
      verbose: 'DEBUG',
      fatal: 'CRITICAL',
    };
    
    export class GcpStructuredLogger implements LoggerService {
      private writeLog(level: LogLevel, message: unknown, context?: string) {
        const logEntry = {
          severity: GCP_SEVERITY_MAP[level],
          message: typeof message === 'string' ? message : JSON.stringify(message),
          context: context || 'App',
          timestamp: new Date().toISOString(),
        };
        // GCP自动采集stdout输出的单行JSON,解析为结构化日志
        process.stdout.write(`${JSON.stringify(logEntry)}\n`);
      }
    
      error(message: unknown, trace?: string, context?: string) {
        this.writeLog('error', trace ? `${message}\n${trace}` : message, context);
      }
      warn(message: unknown, context?: string) {
        this.writeLog('warn', message, context);
      }
      log(message: unknown, context?: string) {
        this.writeLog('log', message, context);
      }
      debug(message: unknown, context?: string) {
        this.writeLog('debug', message, context);
      }
      verbose(message: unknown, context?: string) {
        this.writeLog('verbose', message, context);
      }
    }
    
  2. 在main.ts中启用自定义Logger:
    const app = await NestFactory.create(AppModule, {
      logger: new GcpStructuredLogger(),
    });
    

注意:输出结构化日志时不要添加控制台颜色转义符、自定义装饰前缀等内容,否则会导致GCP无法正确解析JSON结构,再次降级为default级别的非结构化日志。

问题示意图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:39:19