NestJS中GraphQL请求无法通过Pino Logger获取请求头问题
NestJS GraphQL请求中无法提取请求头到Pino日志的解决方案
我使用NestJS v9(搭配Express适配器)和@nestjs/graphql库,遇到问题:GraphQL请求无法提取x-correlation-id请求头并附加到Pino日志消息中,但REST请求下相同配置可正常显示该ID。
当前LoggerModule配置
import { Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { LoggerModule as PinoLoggerModule } from 'nestjs-pino'; @Module({ imports: [ PinoLoggerModule.forRootAsync({ imports: [ConfigModule.forRoot({ isGlobal: true })], useFactory: async (configService: ConfigService) => ({ isGlobal: true, pinoHttp: { level: process.env.LOG_LEVEL || 'info', redact: configService.get<string[]>('logger.redact.fields'), transport: { target: 'pino-pretty', options: { colorize: false, singleLine: true, levelFirst: false, translateTime: "yyyy-mm-dd'T'HH:MM:ss.l'Z'", messageFormat: '{req.headers.x-correlation-id} [{context}] {msg}', ignore: 'pid,hostname,context,req,res.headers', errorLikeObjectKeys: ['err', 'error'], }, }, }, }), inject: [ConfigService], }), ], controllers: [], providers: [], }) export class LoggerModule {}
问题表现
日志仅展示[context] {msg}部分,req.headers.x-correlation-id字段未出现在日志中,仅GraphQL请求存在此问题。
解决方案
1. 确保GraphQL上下文传递请求对象
在GraphQL模块配置中,显式将请求对象注入上下文,让Pino能访问到请求头:
import { GraphQLModule } from '@nestjs/graphql'; @Module({ imports: [ GraphQLModule.forRoot({ // 其他配置(如autoSchemaFile、driver等) context: ({ req }) => ({ req }), }), // 其他模块 ], }) export class AppModule {}
2. 自定义Pino的日志字段映射
修改Pino配置,将x-correlation-id提取为日志根字段,避免依赖req路径的访问限制:
PinoLoggerModule.forRootAsync({ imports: [ConfigModule.forRoot({ isGlobal: true })], useFactory: async (configService: ConfigService) => ({ isGlobal: true, pinoHttp: { level: process.env.LOG_LEVEL || 'info', redact: configService.get<string[]>('logger.redact.fields'), // 自定义属性,提取correlation id customProps: (req) => ({ correlationId: req.headers['x-correlation-id'] || 'unknown', }), transport: { target: 'pino-pretty', options: { colorize: false, singleLine: true, levelFirst: false, translateTime: "yyyy-mm-dd'T'HH:MM:ss.l'Z'", // 修改messageFormat使用根字段的correlationId messageFormat: '{correlationId} [{context}] {msg}', ignore: 'pid,hostname,context,req,res.headers', errorLikeObjectKeys: ['err', 'error'], }, }, }, }), inject: [ConfigService], }),
3. 验证效果
启动服务后,发送带x-correlation-id头的GraphQL请求,日志应正常显示该ID。
内容的提问来源于stack exchange,提问作者mh377
相关产品推荐
相关产品推荐

