Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Above answers did not work for me. In case you are trying to add timestamp to your logs using the latest version of Winston - 3.0.0-rc1, this worked like charm:

    const {transports, createLogger, format} = require('winston');
    const logger = createLogger({
        format: format.combine(
            format.timestamp(),
            format.json()
        transports: [
            new transports.Console(),
            new transports.File({filename: 'logs/error/error.log', level: 'error'}),
            new transports.File({filename: 'logs/activity/activity.log', level:'info'})

I used 'format.combine()'. Since I needed timestamp on all my transports, I added the formatting option within the createLogger, rather than inside each transport. My output on console and on file (activity.log) are as follows:

{"message":"Connected to mongodb","level":"info","timestamp":"2018-02-01T22:35:27.758Z"}
{"message":"Connected to mongodb","level":"info","timestamp":"2018-02-01T22:35:27.758Z"}

We can add formatting to this timestamp in 'format.combine()' as usual using:

format.timestamp({format:'MM-YY-DD'})

I was dealing with the same issue myself. There are two ways I was able to do this.

When you include Winston, it usually defaults to adding a Console transport. In order to get timestamps to work in this default case, I needed to either:

  • Remove the console transport and add again with the timestamp option.
  • Create your own Logger object with the timestamp option set to true.
  • The first:

    var winston = require('winston');
    winston.remove(winston.transports.Console);
    winston.add(winston.transports.Console, {'timestamp':true});
    

    The second, and cleaner option:

    var winston = require('winston');
    var logger = new (winston.Logger)({
        transports: [
          new (winston.transports.Console)({'timestamp':true})
    

    Some of the other options for Console transport can be found here:

  • level: Level of messages that this transport should log (default 'debug').
  • silent: Boolean flag indicating whether to suppress output (default false).
  • colorize: Boolean flag indicating if we should colorize output (default false).
  • timestamp: Boolean flag indicating if we should prepend output with timestamps (default false). If function is specified, its return value will be used instead of timestamps.
  • This is great. I usually wrap this in a dedicated file so that I can easily get my configured logger from any file, i.e., I put the above code (option 2) in a new file logger.js, followed by module.exports = logger; then from any file I do var logger = require('./logger.js') and can then do logger.info('hello') from any file and get the same configuration of Winston. – JHH May 28, 2015 at 8:58 This does not appear to work in the current version of Winston. Try one of the other answers instead. – AverageHelper Apr 14, 2021 at 4:15

    We can do like this also

    var winston = require('winston');
    const { createLogger, format, transports } = require('winston');
    var config = require('../configurations/envconfig.js');
    var loggerLevel = process.env.LOGGERLEVEL ||  config.get('LOGGERLEVEL');
    var logger = winston.createLogger({
      format: format.combine(
        format.timestamp({
          format: 'YYYY-MM-DD HH:mm:ss'
        format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`+(info.splat!==undefined?`${info.splat}`:" "))
      transports: [
        new (winston.transports.Console)({ level: loggerLevel }),
    module.exports = logger;
                    Does this also work for logger.info('Message', someObject)? I setup a custom format using combine and I can't seem to get the someObject included in the log message.
    – SomethingOn
                    Jun 25, 2018 at 19:20
                    I was able to get someObject included by using the following printf statement ${info.timestamp} [${info.level.toUpperCase()}]: ${info.message} ${JSON.stringify(info)}. It includes the level, timestamp and message which I guess I could delete.
    – SomethingOn
                    Jun 25, 2018 at 19:28
    

    You can use built-in util and forever to achieve logging with timestap for your nodejs server. When you start a server add log output as part of the parameter:

    forever start -ao log/out.log server.js
    

    And then you can write util in your server.js

    server.js

    var util = require('util');
    util.log("something with timestamp");
    

    The output will look something like this to out.log file:

    out.log

    15 Mar 15:09:28 - something with timestamp
    

    I took Biswadev's answer and created a stringified JSON object. This way if i need to process the logs later it will be in a well structured format.

    const winston = require('winston');
    const { createLogger, format, transports } = require('winston');
    const dotenv = require('dotenv');
    dotenv.config();
    var logger = createLogger({
        level: 'info',
        format: format.combine(
            format.timestamp({
                format: 'YYYY-MM-DD HH:mm:ss',
            format.printf((info) =>
                JSON.stringify({
                    t: info.timestamp,
                    l: info.level,
                    m: info.message,
                    s: info.splat !== undefined ? `${info.splat}` : '',
                }) + ','
    if (process.env.NODE_ENV !== 'PRODUCTION') {
        logger.add(new transports.Console({ format: winston.format.cli() }));
        // Turn these on to create logs as if it were production
        // logger.add(new transports.File({ filename: 'log/output/error.log', level: 'error' }));
        // logger.add(new transports.File({ filename: 'log/output/warn.log', level: 'warn' }));
        // logger.add(new transports.File({ filename: 'log/output/info.log', level: 'info' }));
    } else {
        logger.add(new transports.File({ filename: 'log/output/error.log', level: 'error' }));
        logger.add(new transports.File({ filename: 'log/output/warn.log', level: 'warn' }));
        logger.add(new transports.File({ filename: 'log/output/info.log', level: 'info' }));
    module.exports = {
        logger,
    

    Usage:

    app.listen(port, () => logger.info(`app is running on port ${port}`));
    

    Output:

    info.log file:

    {"t":"2020-08-06 08:02:05","l":"info","m":"app is running on port 3001","s":""},
    

    Console:

    info:    app is running on port 3001
    

    Although I'm not aware of winston, this is a suggestion. I use log4js for logging & my logs by default look like this

    [2012-04-23 16:36:02.965] [INFO] Development - Node Application is running on port 8090
    [2012-04-23 16:36:02.966] [FATAL] Development - Connection Terminated to  '127.0.0.1' '6379'
    

    Development is the environment of my node process & [INFO|FATAL] is log level

    Maintaining different profiles for logging is possible in log4js. I have Development & Production profiles. Also there are logger types like rolling file appender, console appender, etc. As a addon your log files will be colorful based on the log level [Trace, Info, Debug, Error, Fatal] ;)

    log4js will override your console.log It is a configurable parameter now in 0.5+

    we could use console-stamp to add timestamp and log level to the existing console: require('console-stamp')(console, '[yyyy-mm-dd HH:MM:ss.l]')

    See https://github.com/starak/node-console-stamp for the details

    Sometimes default timestamp format can be not convenient for you. You can override it with your implementation.

    Instead of

    var winston = require('winston');
    var logger = new (winston.Logger)({
    transports: [
      new (winston.transports.Console)({'timestamp':true})
    

    you can write

    var winston = require('winston');
    var logger = new (winston.Logger)({
    transports: [
      new (winston.transports.Console)({
         'timestamp': function() {
            return <write your custom formatted date here>;
    

    See https://github.com/winstonjs/winston#custom-log-format for the details

    Another solution is wrapping the logger into a file that exports some functions like logger.info(), logger.error(), etc. then you just pass an extra key to be sent on every message log.

    loggerService.js

    const logger = winston.createLogger({ ... })
    function handleLog(message, level) {
      const logData = {
        timestamp: Date.now(),
        message,
      return logger[level](logData)
    function info(message) {
      handleLog(message, 'info')
    function error(message) {
      handleLog(message, 'error')
    function warn(message) {
      handleLog(message, 'warn')
    module.exports = {
      info,
      error,
    

    whatever-file.js

    const logger = require('./services/loggerService')
    logger.info('Hello World!')
    

    your-log.log

    {"timestamp":"2019-08-21 06:42:27","message":"Hello World!","level":"info"}
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.