Winston: 3.0.0-rc1 - Unable to log timestamps

Created on 28 Dec 2017  路  13Comments  路  Source: winstonjs/winston

I followed the example from the documentation, and created a logger as shown below:

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

const logger = createLogger(
    {
        level: 'info',
        transports: [new transports.Console({
            showLevel: false,
            colorize: true,
            timestamp: true
        })
        ]
    }
);

logger.info('Server started');

But, I can seem to get the time stamps working. I get the following output in black and white:

{"message":"Server started","level":"info"}

Based on the documentation at https://github.com/winstonjs/winston/blob/master/docs/transports.md#console-transport, setting timestamp flag to true should put a default timestamp.

I even tried by returning a custom timestamp by passing a function but even that doesn't show up. Perhaps, I missed something but it seems like none of the options work, ie. colorize, showLevel, timestamp.

Or is the documentation out of sync?

Most helpful comment

@armadillojim

Use the printf format like this:

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

// Define your custom format with printf.
const myFormat = printf(info => {
  return `${info.timestamp} ${info.level}: ${info.message}`
})

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

logger.info('foo') // -> 2018-02-21T03:55:19.236Z info: foo

All 13 comments

No updates on this issue yet? I am facing same issue. Works on [email protected] but not on [email protected]

Have a look at the formats you can use with [email protected].

const { createLogger, format, transports } = require('winston')

const logger = createLogger({
  level: 'info',
  transports: new transports.Console({
    format: format.combine(
      format.timestamp({
        format: 'YYYY-MM-DD' // Optional for choosing your own timestamp format.
      }),
      format.json()
    )
  })
})

logger.info('Server started')

The example prints out the following:

{"message":"Server started","level":"info","timestamp":"2018-01-17T15:20:55.621Z"}

Or with the formatting option:

{"message":"Server started","level":"info","timestamp":"2018-01-17"}

why format.timestamp does not work without format.json being declared after format.timestamp?

I just want a simple at the beginning of line just as it was before, I don't want json formatting
[2018-01-17T15:20:55.621Z] INFO sdfsdfsdfsdfdfasfsadf, how can I achieve this?

On version 2.3.1 I can achieve:
2018-02-12T18:50:25.472Z - INFO: Starting up the process

With:

const winston = require('winston');

const logger = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)({ timestamp: true, colorize: true}),
  ],
  exceptionHandlers: [
    new (winston.transports.Console)({ timestamp: true, colorize: true }),
  ],
  level: 'INFO',
  levels: {
    FATAL: 0,
    ERROR: 1,
    WARN: 2,
    INFO: 3,
    DEBUG: 4
  },
  colors: {
    INFO: 'blue',
    WARN: 'green',
    ERROR: 'yellow',
    FATAL: 'red'
  }
});

module.exports = logger

I was hoping to use the "simple" line-of-text logging. I tried following the docs:

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

But that winds up mixing text and JSON like:

info: GET /alice?bob {"timestamp":"2018-02-21T02:52:31.452Z"}

I was hoping to prefix each line with the timestamp, and for the timestamp to be printed alone. Something like:

2018-02-21T02:52:31.452Z info: GET /alice?bob

but the comments above indicate that's only possible using the older style of passing options to the Console() constructor.

Any suggestions? Or am I asking the wrong question? That is, do log analyzers prefer JSON these days? TIA.

@armadillojim

Use the printf format like this:

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

// Define your custom format with printf.
const myFormat = printf(info => {
  return `${info.timestamp} ${info.level}: ${info.message}`
})

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

logger.info('foo') // -> 2018-02-21T03:55:19.236Z info: foo

@ChrisAlderson you are the man, also if you want to display the splat I enhanced your answer with:
`
const vsprintf = require('sprintf-js').vsprintf;

const myFormat = printf(info =>${info.timestamp} ${info.level}: ${vsprintf(info.message, ...(info.splat || []))})
`

@ChrisAlderson, thanks so much! The documentation did not seem clear on this to me. Much appreciated!

Thanks for helping folks out @ChrisAlderson. Contributions on documentation to improve explaining how formats work would be most welcome 馃憤

Note: be careful when using timestamp with metadata, apparently using both format functions leads to putting the time stamp as info.metadata.timestamp instead of info.timestamp

In case someone needs to log additional metadata, including error's stack, the snippet below does the job (PS: example uses a simple output format). The snipped below targets @armadillojim expected output (described earlier ) and is a tinny improvement based on @ChrisAlderson's answer.

As described by @OzzyTheGiant, when using timestamp with metadata, timestamp is accessed as a property of metadata, not info.

import winston from 'winston';

// Creates the default formatter.
// We deconstruct "metadata" into "timestamp" and "meta", and use them in the default formatter.
const logFormat = winston.format.printf((info) => {
  const { timestamp, ...meta } = info.metadata;
  return `${timestamp} ${info.level}: ${info.message} ${JSON.stringify(meta)}`;
});

// Creates the logger. "padLevels", "colorize" and "padLevels" are optional.
logger = winston.createLogger({
  format: winston.format.combine(
    winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
    winston.format.padLevels(),
    winston.format.metadata(),
    winston.format.errors({ stack: true }),
    logFormat,
    winston.format.colorize({ all: true })
  ),
  transports: [new winston.transports.Console()],
});



logger.info('Simple log');
logger.info('Logger Info', { logLevel: 'info', colorize: { all: true } });
logger.error('', new Error('Logger error'));

Output:

// 2019-05-11 00:20:53 info:     Simple log {}
// 2019-05-11 00:20:53 info:     Logger Info {"logLevel":"info","colorize":{"all":true}}
// 2019-05-11 00:20:53 error:    Logger error {"stack":"Logger error\n    at ...

why format.timestamp does not work without format.json being declared after format.timestamp?

This is still the thing 2 year later.

this works
format: winston.format.combine( winston.format.timestamp(), winston.format.json() ),

this doesn't
format: winston.format.combine( winston.format.json(), winston.format.timestamp() ),

for writing logs to file

Was this page helpful?
0 / 5 - 0 ratings