37

I'm trying to get Winston to pretty print to the console, so I stuck this in a file and ran it with node:

var winston = require('winston');
winston.cli();
winston.data({
  a: "test",
  of: "many",
  properties: {
    like: "this"
  }
});
winston.data('data', {
  a: "test",
  of: "many",
  properties: {
    like: "this"
  }
});

The terminal spit back the following (not exactly pretty) messages:

data:     a=test, of=many, like=this
data:    data a=test, of=many, like=this

I'm following the instructions on the Winston Readme ("Using winston in a CLI tool"). Am I misreading something? Missing a setting somewhere?

JoBu1324
  • 7,751
  • 6
  • 44
  • 61

7 Answers7

32

I figured out the answer (the documentation is incorrect). If you use the constructor, and manually add transports, you can set options, both for winston, and for individual transports. Certain options need to be added to winston directly, while others need to be added to the transport.

E.g.:

var winston = require('winston');
var logger = new (winston.Logger)({
  levels: {
    trace: 0,
    input: 1,
    verbose: 2,
    prompt: 3,
    debug: 4,
    info: 5,
    data: 6,
    help: 7,
    warn: 8,
    error: 9
  },
  colors: {
    trace: 'magenta',
    input: 'grey',
    verbose: 'cyan',
    prompt: 'grey',
    debug: 'blue',
    info: 'green',
    data: 'grey',
    help: 'cyan',
    warn: 'yellow',
    error: 'red'
  }
});

logger.add(winston.transports.Console, {
  level: 'trace',
  prettyPrint: true,
  colorize: true,
  silent: false,
  timestamp: false
});

logger.add(winston.transports.File, {
  prettyPrint: false,
  level: 'info',
  silent: false,
  colorize: true,
  timestamp: true,
  filename: './nKindler.log',
  maxsize: 40000,
  maxFiles: 10,
  json: false
});
JoBu1324
  • 7,751
  • 6
  • 44
  • 61
32

If you're using winston@3.0.0-rc0 then the accepted answer won't work. Try the following:

const winston = require("winston");
let date = new Date().toISOString();
const logFormat = winston.format.printf(function(info) {
  return `${date}-${info.level}: ${JSON.stringify(info.message, null, 4)}\n`;
});
const logger = winston.createLogger({
  transports: [
    new winston.transports.Console({
      level: level,
      format: winston.format.combine(winston.format.colorize(), logFormat)
    })
  ]
});

The logs will have the following format:

It's colored BTW

2018-03-01T19:49:54.042Z-info: "----- Customer Details ------"

2018-03-01T19:49:54.042Z-info: [
    {
        "A": 1,
        "B": 2
    }
]
orad
  • 15,272
  • 23
  • 77
  • 113
Sam Gh
  • 530
  • 5
  • 10
  • This should become the accepted answer @JoBu1324 – mwryl Jul 02 '21 at 06:01
  • 3
    This hardcodes the date to one value, and won't log the correct date in the log messages - they will all be the same (as shown in the example). – sneak Feb 05 '22 at 16:48
13

Here's a solution for Winston v3+

  let winstonFormat = winston.format.json();
  if (NODE_ENV == "development") {
    winstonFormat = winston.format.combine(winston.format.json(), winston.format.prettyPrint());
  }

  const log = winston.createLogger({
    level: "info",
    format: winstonFormat,
    defaultMeta: {app: "myapp"},
    transports: [
      new winston.transports.File({filename: "/dev/stderr", level: "warn"}),
      new winston.transports.File({filename: "/dev/stdout"}),
    ],
  });
chrishiestand
  • 2,800
  • 1
  • 25
  • 25
3

I took @partycoder's answer and trimmed it down to use only the default logging levels that come with winston. It also doesn't reverse the order of the errors. 0 = highest priority.

winston.addColors({
  silly: 'magenta',
  debug: 'blue',
  verbose: 'cyan',
  info: 'green',
  warn: 'yellow',
  error: 'red'
});

winston.remove(winston.transports.Console);
winston.add(winston.transports.Console, {
  level: process.env.LOG_LEVEL,
  prettyPrint: true,
  colorize: true,
  silent: false,
  timestamp: false
});
timetofly
  • 2,957
  • 6
  • 36
  • 76
0

I faced the same issue too but I came to meet it on git, and found some interesting trick that might be helpful about it. issue #1217

First of all, the trick is in using

JSON.stringify(jsonData, null, 4) // This helps indent lines and make them readable

You can see it in this visual studio code screenshoot below for clear documentation how to use JSON.stringify

For example if you were using a console transporter you would create it like this

    transports: [
        new winston.transports.Console({
            format: printf((info) => {
                return `${info.timestamp} [${info.label}] [${info.level}] : ${info.message}\n 
            ${JSON.stringify(info.meta, null, 4)}`; // Meta as additional data you provide while logging
                ;
            })
        })
    ]

And use it like

Logger.info("Message text", { meta: metaDataHere } )
0

I think this is a slightly better solution than Sam Gh's one:

const winston = require("winston");

const logFormat = winston.format.printf(function(info) {
  return `${info.timestamp}-${info.level}: ${JSON.stringify(info.message, null, 4)}\n`;
});

const logger = winston.createLogger({
  transports: [
    new winston.transports.Console({
      level: level,
      format: winston.format.combine(winston.format.timestamp()
                                     winston.format.colorize(), 
                                     logFormat)
    })
  ]
});

In this way, the log entry's timestamp is correct and not the hardcoded one.

Simone
  • 11,655
  • 1
  • 30
  • 43
0

For the ones using NestJS

const app = await NestFactory.create<NestExpressApplication>(AppModule, {
logger: WinstonModule.createLogger({
  exitOnError: false,
  transports: [
    new transports.Console({
      format: winston.format.combine(
        winston.format.errors({ stack: true }),
        utilities.format.nestLike('App name', {
          colors: true,
          prettyPrint: true,
        }),
      ),
    }),
    new LogtailTransport(new Logtail(process.env.logTail)),
  ],
}),
});

Basically

utilities.format.nestLike('App Name', {
      colors: true,
      prettyPrint: true,
    }),

does the trick

RicardoVallejo
  • 793
  • 7
  • 11