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

如何在Next.js中为Pino Logger配置多管道分级别日志

在Next.js中使用Pino Logger按级别分文件写入并转换日志

你的代码核心问题是重复定义了transport.pipeline属性,JavaScript对象中重复的键会被后续值覆盖,因此只有最后一个error相关的管道生效,导致info.log无内容;同时全局日志级别设为info,所有info及以上级别的日志都会进入这个唯一管道,而pino/file的level配置不会自动过滤日志,所以error.log会同时包含info和error级别的内容。

以下是两种可行的解决方案:

方案一:使用@pinojs/multi-stream实现分流与转换

这种方式灵活性更高,适合需要自定义转换逻辑的场景:

  1. 安装依赖:
npm install @pinojs/multi-stream pino
  1. 配置Logger(示例文件:logger.js):
const pino = require('pino');
const { multistream } = require('@pinojs/multi-stream');
const fs = require('fs');
const { Transform } = require('stream');

// Info级别日志转换流
const infoTransform = new Transform({
  objectMode: true,
  transform(chunk, encoding, callback) {
    // 编写info日志转换逻辑,比如添加处理时间字段
    chunk.processedAt = new Date().toISOString();
    callback(null, chunk);
  }
});

// Error级别日志转换流
const errorTransform = new Transform({
  objectMode: true,
  transform(chunk, encoding, callback) {
    // 编写error日志转换逻辑,比如补充错误上下文
    chunk.errorContext = chunk.stack || '无堆栈信息';
    callback(null, chunk);
  }
});

// 创建文件写入流
const infoFileStream = fs.createWriteStream('./logs/info.log', { flags: 'a' });
const errorFileStream = fs.createWriteStream('./logs/error.log', { flags: 'a' });

// 组合转换流与文件流
const infoPipeline = infoTransform.pipe(pino.destination({ dest: infoFileStream, sync: false }));
const errorPipeline = errorTransform.pipe(pino.destination({ dest: errorFileStream, sync: false }));

module.exports = pino({
  level: 'info' // 全局捕获info及以上级别日志
}, multistream([
  // 仅将info级别日志发送到info管道
  { 
    stream: infoPipeline, 
    filter: (log) => log.level === pino.levels.values.info 
  },
  // 将error及以上级别日志发送到error管道
  { stream: errorPipeline, level: 'error' }
]));

方案二:使用Pino v8+的多Transport配置

如果你的Pino版本是v8及以上,可以直接配置多个transport管道,每个管道对应一个级别和转换逻辑:

const pino = require('pino');

module.exports = pino({
  level: 'info'
}, {
  transports: [
    // Info级别日志管道
    {
      pipeline: [
        { target: './info-transform-transport.mjs' }, // 自定义转换transport
        { 
          target: 'pino/file', 
          options: { destination: './logs/info.log' },
          // 过滤仅保留info级别日志
          filter: (log) => log.level === pino.levels.values.info
        }
      ]
    },
    // Error级别日志管道
    {
      pipeline: [
        { target: './error-transform-transport.mjs' }, // 自定义转换transport
        { 
          target: 'pino/file', 
          options: { destination: './logs/error.log' },
          level: 'error'
        }
      ]
    }
  ]
});

自定义转换Transport示例(info-transform-transport.mjs)

确保自定义transport符合Pino要求,导出一个返回转换流的函数:

import { Transform } from 'stream';

export default function (options) {
  return new Transform({
    objectMode: true,
    transform(chunk, enc, cb) {
      // 编写你的转换逻辑
      chunk.transformedBy = 'info-transform';
      cb(null, chunk);
    }
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:10:23