如何配置NestJS日志匹配GCP Stackdriver日志严重级别?
问题根因
NestJS默认输出的是纯文本格式日志,没有遵循GCP Cloud Logging(原Stackdriver)的结构化日志规范携带标准severity字段,GCP无法识别纯文本内容里打印的DEBUG/INFO等级别标识,会默认把所有这类非结构化日志归类为default严重级别,因此按指定verbosity级别筛选时无法匹配到对应日志。
可行配置方案
方案1:使用官方适配的结构化日志库(推荐,无业务代码侵入)
通过替换NestJS默认Logger适配器的方式实现,不需要修改业务中已写的日志调用逻辑:
- 安装依赖
npm install @google-cloud/logging-winston nest-winston winston - 在应用入口
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行格式日志即可:
- 实现自定义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); } } - 在
main.ts中启用自定义Logger:const app = await NestFactory.create(AppModule, { logger: new GcpStructuredLogger(), });
注意:输出结构化日志时不要添加控制台颜色转义符、自定义装饰前缀等内容,否则会导致GCP无法正确解析JSON结构,再次降级为
default级别的非结构化日志。
内容的提问来源于stack exchange,提问作者Mule
相关产品推荐
相关产品推荐

