NestJS下nestjs-pino输出ECS格式日志相关问题咨询
NestJS-Pino 适配 Elastic ECS 格式问题解决方案
1. 重复req字段清理方法
核心原因是pino-http默认会把原始请求对象挂载到日志根节点,可通过以下三种方案解决:
- 方案一:关闭pino-http默认请求挂载,在nestjs-pino初始化配置中添加
pinoHttp: { autoLogging: { ignorePaths: [] }, customProps: () => ({}) },禁用默认的req/res自动注入逻辑,仅保留你自定义格式化器生成的http.request字段。 - 方案二:自定义格式化器中显式移除req字段,在处理日志对象时直接解构排除原始req字段,pino序列化时会自动忽略未返回的字段,示例代码:
const ecsFormat = require('@elastic/ecs-pino-format')() const customFormatter = (obj) => { // 解构排除原始req、res字段 const { req, res, ...restLog } = obj // 你的ECS字段转换逻辑 const ecsLog = ecsFormat(restLog) // 如果是通过obj.res.log.bindings()提取的请求参数,提取完成后不需要将原始req字段纳入返回值 ecsLog.http = { request: /* 你提取的请求参数 */ } return ecsLog }
- 方案三:配置pino序列化器忽略req字段,在pino配置中添加
serializers: { req: () => undefined },直接让pino序列化时跳过req字段的输出。
2. @elastic/ecs-pino-format Fastify兼容问题解决
不兼容的核心原因是Fastify的请求/响应对象结构和Express存在差异,官方ECS格式化器默认只适配了Express的结构,可通过以下方案解决:
- 不直接使用官方ecs-pino-format包,自定义轻量格式化逻辑,手动将Fastify的req对象字段映射到ECS规范对应的字段上,适配性更高也更灵活。
- 重写ECS格式化器的请求处理逻辑,传入适配Fastify的请求字段提取方法,示例逻辑:
const fastifyReqToEcs = (req) => { return { method: req.method, url: { path: req.url, full: req.raw.url }, headers: req.headers, remote: { address: req.ip, port: req.socket?.remotePort } } }
直接调用该方法生成http.request字段即可,不需要依赖官方包的自动转换逻辑。
内容的提问来源于stack exchange,提问作者Georgios Kampitakis
相关产品推荐
相关产品推荐

