← 中文资源

简体中文版本

Pino 多传输器日志路由

让 Pino 日志并行分发到多个传输器:错误级别单独进检索引擎,普通日志走标准输出,本地开发用彩色美化输出。

阅读英文原文

示例说明

不同级别日志的消费路径天然不同:全量日志上 stdout 交给采集器,错误日志需要立即可检索、可告警。Pino 的 transports 数组让一行日志同时进入多个目的地,每条传输器可以设独立的级别门槛——错误传输器只收 error 及以上,既省索引成本又保证告警延迟。开发态与生产态的传输器配置在此处分流。

技术要点

  • 多传输器并行分发同一行日志
  • 每个传输器可独立设置级别门槛
  • 环境分支切换开发与生产配置

代码解读

生产分支的两个传输器分别把 info 级写向 stdout 文件描述符、error 级批量送进 Elasticsearch 专用索引,flushInterval 控制批量刷新窗口;开发分支只剩彩色美化控制台输出。base 字段给全部日志行附加服务与区域维度。unref 的心跳定时器不阻塞进程退出。

使用建议

传输器跑在工作线程,进程退出前要 flush。Elasticsearch 写入失败要有兜底防止静默丢日志。索引按日期滚动控制体积。

代码示例

import { pino } from 'pino';

const isProd = process.env.NODE_ENV === 'production';

const logger = pino({
  level: process.env.LOG_LEVEL ?? 'info',
  base: { service: 'billing', region: 'eu-1' },
  transports: isProd
    ? [
        {
          level: 'info',
          target: 'pino/file',
          options: { destination: 1, mkdir: false },
        },
        {
          level: 'error',
          target: 'pino-elasticsearch',
          options: {
            node: 'http://elastic:9200',
            index: 'billing-errors',
            flushInterval: 2000,
          },
        },
      ]
    : [
        {
          target: 'pino-pretty',
          options: { colorize: true, translateTime: 'SYS:HH:MM:ss' },
        },
      ],
});

logger.info({ invoiceId: 'inv-9', amount: 4200 }, 'invoice settled');
logger.warn({ retries: 2 }, 'settlement retried');
logger.error({ invoiceId: 'inv-10', reason: 'gateway timeout' }, 'settlement failed');

setInterval(() => {
  logger.debug('heartbeat');
}, 30_000).unref();