NestJS全局注入nestwinston后自定义日志对象无法显示问题
解决NestJS全局注入nest-winston后自定义对象日志不显示的问题
问题根源
当用nest-winston替换NestJS全局Logger后,Nest原生Logger的方法签名与nest-winston的实现不匹配:
- 原生
Logger的log方法是log(message: any, context?: string) - nest-winston实现的
LoggerService将第二个参数视为元数据(meta),第三个参数才是context
你调用this.logger.log("my message", {myValue: true})时,{myValue: true}被当成了context,真正的元数据为空,所以日志里出现空对象{}。
解决方案
1. 修正日志调用参数顺序
按照nest-winston的参数规则调用,明确传递元数据和context:
import { Injectable, Logger } from '@nestjs/common'; @Injectable() export class Bootstrapper { constructor(private readonly logger: Logger) { // 格式:message, meta, context this.logger.log("my message", {myValue: true}, "Bootstrapper"); } }
2. 直接使用nest-winston的WinstonLogger
放弃Nest原生Logger,注入WinstonLogger以获得更贴合Winston的API支持:
import { Injectable } from '@nestjs/common'; import { WinstonLogger } from 'nest-winston'; @Injectable() export class Bootstrapper { constructor(private readonly logger: WinstonLogger) { // 直接传递元数据 this.logger.log("my message", {myValue: true}); // 或使用结构化日志对象 this.logger.log({ message: "my message", myValue: true, context: "Bootstrapper" }); } }
3. 配置双格式日志(控制台美化+Grafana JSON)
调整Winston格式器,同时满足控制台可读性和Grafana的结构化需求:
import { Module } from '@nestjs/common'; import { WinstonModule } from 'nest-winston'; import * as winston from 'winston'; @Module({ imports: [ WinstonModule.forRoot({ transports: [ // 控制台美化格式 new winston.transports.Console({ format: winston.format.combine( winston.format.timestamp(), winston.format.colorize(), winston.format.printf(({ timestamp, level, message, context, ...meta }) => { const metaStr = Object.keys(meta).length ? `\n${JSON.stringify(meta, null, 2)}` : ''; return `[${timestamp}] ${level} [${context}] ${message}${metaStr}`; }) ) }), // Grafana专用JSON格式日志 new winston.transports.File({ filename: 'logs/grafana.log', format: winston.format.combine( winston.format.timestamp(), winston.format.json() ) }) ] }), ], }) export class AppModule {}
内容的提问来源于stack exchange,提问作者johnykes
相关产品推荐
相关产品推荐

