Winston: Console logging is not colorized.

Created on 10 Nov 2017  ·  22Comments  ·  Source: winstonjs/winston

I'm trying to colorize the console output and it's not working. The output is all the same (white) color. I'm on 3.0.0-rc1.

const winston = require('winston');
const logLevels = {
  levels: {
    error: 0,
    warn: 1,
    info: 2,
    http: 3,
    sql: 4,
    debug: 5
  },
  colors: {
    error: "red",
    warn: "darkred",
    info: "black",
    http: "green",
    sql: "blue",
    debug: "gray"
  }
};
winston.addColors(logLevels);
const logger = winston.createLogger({...});
logger.add(new winston.transports.Console({colorize: true}));

I also tried the suggestion here but that's not working either:

logger.add(new winston.transports.Console({format: winston.format.combine(formatter, winston.format.colorize())}));

Thanks,
Alvaro

Most helpful comment

I was able to get it partially working using the documentation for logform.

  const alignedWithColorsAndTime = winston.format.combine(
    winston.format.colorize(),
    winston.format.timestamp(),
    winston.format.align(),
    winston.format.printf(info => `${info.timestamp} [${info.level}]: ${info.message}`),
  );

Not sure how to handle dumping the JSON arguments.

Update here is what I worked out:

  const alignedWithColorsAndTime = winston.format.combine(
    winston.format.colorize(),
    winston.format.timestamp(),
    winston.format.align(),
    winston.format.printf((info) => {
      const {
        timestamp, level, message, ...args
      } = info;

      const ts = timestamp.slice(0, 19).replace('T', ' ');
      return `${ts} [${level}]: ${message} ${Object.keys(args).length ? JSON.stringify(args, null, 2) : ''}`;
    }),
  );

screen shot 2017-11-13 at 10 55 05 am

All 22 comments

I was able to get it partially working using the documentation for logform.

  const alignedWithColorsAndTime = winston.format.combine(
    winston.format.colorize(),
    winston.format.timestamp(),
    winston.format.align(),
    winston.format.printf(info => `${info.timestamp} [${info.level}]: ${info.message}`),
  );

Not sure how to handle dumping the JSON arguments.

Update here is what I worked out:

  const alignedWithColorsAndTime = winston.format.combine(
    winston.format.colorize(),
    winston.format.timestamp(),
    winston.format.align(),
    winston.format.printf((info) => {
      const {
        timestamp, level, message, ...args
      } = info;

      const ts = timestamp.slice(0, 19).replace('T', ' ');
      return `${ts} [${level}]: ${message} ${Object.keys(args).length ? JSON.stringify(args, null, 2) : ''}`;
    }),
  );

screen shot 2017-11-13 at 10 55 05 am

After two hours I managed to get the colors working, thanks @Xeoncross !

started winston and also got console without colors...
i was using next transport defining code:

new winston.transports.Console({
  format: winston.format.simple()
})

after reading this thread i did like this:

new winston.transports.Console({
  format: winston.format.combine(
            winston.format.simple(),
            winston.format.colorize()
          )
})

and got no difference.
so i changed position of colorize format to 1st and got colors working

new winston.transports.Console({
  format: winston.format.combine(
            winston.format.colorize(),
            winston.format.simple()
          )
})

Thanks @abrakadobr ! that did the trick.

nothing here worked for me, still no colors, and shifting colorize to the top caused the info field to log encoded strings

I created a gist that shows how to use winston & morgan logging in a simple expressjs app.

Thanks @Xeoncross! Adding winston.format.colorize() to my format worked. Interesting that this isn't in the docs. Or at least I couldn't find it in the docs.

I love the new flexibility, but I hope it gets better documentation. I just spent too long getting this to work. A plug-n-play example for those of us who were using winston.cli() would go a long way, something similar to @Xeoncross’s example.

Anyone know how to do it with the current release version? A release candidate version is not an option.

In reading the code you can also send all to the colorize as an option to colorize the entire log.

colorize({ all: true })

@markhealey I already removed winston dependency from my package.json and then I read your message. Thank you :+1:

Thx @Xeoncross. Take a look at: https://github.com/winstonjs/logform/blob/master/timestamp.js. You can format timestamp with format opt param. But be careful with timezone

format.combine(
    format.colorize(),
    format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
    format.align(),
    format.printf(info => {
        const { timestamp, level, message, ...extra } = info;

        return `${timestamp} [${level}]: ${message} ${
            Object.keys(extra).length ? JSON.stringify(extra, null, 2) : ''
        }`;
    }),
)

format.colorize({all:true} does not really work if timestamp is included, here is a working example to colorize the whole line:

const colorizer = winston.format.colorize();

const logger = winston.createLogger({
  level: 'debug',
  format: combine(
    winston.format.timestamp(),
    winston.format.simple(),
    winston.format.printf(msg => 
      colorizer.colorize(msg.level, `${msg.timestamp} - ${msg.level}: ${msg.message}`)
    )
  ),
  transports: [
    new transports.Console(),
  ]

});

check my full featured logger

Thanks @abrakadobr, your solution worked for me.

@tommuhm I see the defect now. There isn't a built-in format option for colorize if one does indeed want to colorize the entire printf. Does this make sense to you?

const { createLogger, format, transports } = require('../');

const logger = createLogger({
  level: 'debug',
  format: format.combine(
    format.timestamp(),
    format.simple(),
    format.printf(info => `${info.timestamp} - ${info.level}: ${info.message}`),
    format.colorize({ all: true })
  ),
  transports: [
    new transports.Console(),
  ]
});

logger.error('wowza');

The tricky bit is having the colorizer known when an info has been "serialized" (i.e. when info[MESSAGE] has been set to a string). Follow-up PR to logform shortly – thanks for digging through it!

@Xeoncross we can also achieve the same in a much simpler way

const { createLogger, format, transports } = require('winston');
const { combine, timestamp, colorize, printf } = format;

const level = process.env.LOG_LEVEL || 'debug';

const myFormat = printf(({ level, message, label, timestamp }) => {
    return `${timestamp} ${level}: ${message}`;
});

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

reference: https://www.npmjs.com/package/winston#using-custom-logging-levels

i am using winston for logging in cloudwatch and trying to add color but instead of color symbols appear.. I try all solutions mention above. below is my code

const winston = require('winston');
const {transports, format, createLogger  } = winston;
const { combine,errors,timestamp} = format;

const colorizer = winston.format.colorize();


const logger = createLogger({
    level:  process.env.LOG_LEVEL,
    prettyPrint : true,
    format: combine(
        winston.format.timestamp(),
        winston.format.simple(),
        winston.format.printf(msg =>
            colorizer.colorize(msg.level, `${msg.timestamp} - ${msg.level}: ${msg.message}`)
        )
    ),
    transports: [
        new transports.Console()
    ]
});

module.exports = {logger};

and in cloudwatch console output is

2019-08-22T13:00:03.325Z - debug: res by id: [
{
    "isActive": true,
    "value": "fNUMheWiwXayKsaYCbUeA7Gg7BtEPIUbakB56XH1",
    "id": "oehlwqlcve",
    "userId": "6b347b41-ddef-4842-83a0-1cd5ca358482"
}
]

this [39m apear instead of color. Any suggestion?

-22T13:00:03.325Z - debug: res by id: [

I'm having the same issue as well. Did you manage to fix it?

-22T13:00:03.325Z - debug: res by id: [

I'm having the same issue as well. Did you manage to fix it?

Any updates on that? Did you solve it somehow?

@Xeoncross we can also achieve the same in a much simpler way

const { createLogger, format, transports } = require('winston');
const { combine, timestamp, colorize, printf } = format;

const level = process.env.LOG_LEVEL || 'debug';

const myFormat = printf(({ level, message, label, timestamp }) => {
  return `${timestamp} ${level}: ${message}`;
});

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

reference: https://www.npmjs.com/package/winston#using-custom-logging-levels

That did the trick for me in iTerm on MacOS

Was this page helpful?
0 / 5 - 0 ratings