Search code examples
typescriptpinojs

How to write logs to file and console using PINO?


I am able to write logs to a log file with below pino implementation.

Can anyone please let me now if it is possible to log to console at the same time to control the 'console.log()' frenzy.

  1. Node Version : 21.6.1
  2. Typescript Version : 5.3.3
  3. Pino Version : 8.18.0
  4. Pino Pretty Version : 10.3.1
import pino from 'pino';
import { getEnvConfig } from "config/env";

const envConfig = getEnvConfig();
const logdir: string = envConfig.log_dir;
const logfile: string = `${logdir}/appName-${new Date(Date.now()).toISOString().split('T')[0]}.log`;

export const logger = pino({
    level: envConfig.log_level ?? "info",
    formatters: {
        bindings: (bindings) => {
            return { pid: bindings.pid, host: bindings.hostname, node_version: process.version };
        },
        level: (label: string) => {
            return { level: label.toUpperCase() };
        },
    },
    timestamp: pino.stdTimeFunctions.isoTime,
    transport: ({ target: 'pino/file', options: { destination: logdir, mkdir: true } }),
});

Solution

  • According to the docs, you can use pipelines instead to specify multiple transports which allows you to maintain your existing level formatters. pino-pretty uses the STDIN and STDOUT so it should output to the console.

    import pino, { LoggerOptions } from 'pino';
    import { getEnvConfig } from "config/env";
    
    const envConfig = getEnvConfig();
    const logdir: string = envConfig.log_dir;
    const logfile: string = `${logdir}/appName-${new Date(Date.now()).toISOString().split('T')[0]}.log`;
    
    const pinoOptions: LoggerOptions = {
        level: envConfig.log_level ?? "info",
        formatters: {
            bindings: (bindings) => {
                return { pid: bindings.pid, host: bindings.hostname, node_version: process.version };
            },
            level: (label: string) => {
                return { level: label.toUpperCase() };
            },
        },
        timestamp: pino.stdTimeFunctions.isoTime,
        transport: ({
            pipeline: [{
                target: 'pino-pretty', // must be installed separately
            },
            {
                target: 'pino/file', options: { destination: logdir, mkdir: true },
            },
            ],
        }
        ),
    }
    export const logger = pino(pinoOptions);