10

I am sharing this as I struggled to get a pino logger to write to both STDOUT and a log file:

const dest = new stream.PassThrough();
dest.pipe(process.stdout);
dest.pipe(fs.createWriteStream('/logs/file.log', { flags: 'a' }));
const logger = pino({ level: 'info' }, dest);

As this appears very low level, I wonder if this is the right way to do this.

Olivier D.
  • 164
  • 1
  • 11

2 Answers2

11

A bit late but pino-multi-stream may be what you want. I followed this section here and it works for me in TypeScript for my purpose. You could try something like this:

const fs = require('fs');
const pinoms = require('pino-multi-stream')

const streams = [
  { stream: process.stdout },
  { stream: fs.createWriteStream('/logs/file.log', { flags: 'a' }) },
]

const logger = pino({ level: 'info' }, pinoms.multistream(streams));
Lee Goddard
  • 10,680
  • 4
  • 46
  • 63
wtwtwt
  • 368
  • 4
  • 11
  • 7
    From 10th June 2022, `pino-multi-stream` is now deprecated (https://www.npmjs.com/package/pino-multi-stream) and the repo has been archived (https://github.com/pinojs/pino-multi-stream). Pino 7/8 support multiple streams so it is recommended to use the native support instead – Woodz Nov 22 '22 at 05:11
  • There is also a performace hit using pino-multi-stream, don't use it if performance is important. – Brian Jul 01 '23 at 02:28
7

if you are using pino 7+ you can just use the following:

const transport = pino.transport({
  targets: [
    {
      level: 'trace',
      target: 'pino/file',
      options: {
        destination: logPath,
      },
    },
    {
      level: 'trace',
      target: 'pino-pretty',
      options: {},
    },
  ],
});

export const log = pino(options, transport);
Or Yaacov
  • 3,597
  • 5
  • 25
  • 49