Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to customize timestamp format? #1134

Closed
alvaro1728 opened this issue Nov 10, 2017 · 18 comments
Closed

How to customize timestamp format? #1134

alvaro1728 opened this issue Nov 10, 2017 · 18 comments

Comments

@alvaro1728
Copy link

I'm using 3.0.0-rc1 and the docs aren't clear on how to customize the timestamp's format. Please help.

Thanks,
Alvaro

@youngkylejan
Copy link

you can read the source code to help yourself customize the format. i can give you an example of mine.

const winston = require('winston');
const moment = require('moment');
const util = require('util');
const MESSAGE = Symbol.for('message');

const logger = winston.createLogger({
    level: 'info',
    format: winston.format.combine(
        winston.format(function(info, opts) {
            prefix = util.format('[%s] [%s]', moment().format('YYYY-MM-DD hh:mm:ss').trim(), info.level.toUpperCase());
            if (info.splat) {
                info.message = util.format('%s %s', prefix, util.format(info.message, ...info.splat));
            } else {
                info.message = util.format('%s %s', prefix, info.message);
            }
            return info;
        })(),
        winston.format(function(info) {
            info[MESSAGE] = info.message + ' ' + JSON.stringify(
                Object.assign({}, info, {
                    level: undefined,
                    message: undefined,
                    splat: undefined
                })
            );
            return info;
        })()
    ),
    transports: [
        new winston.transports.Console(),
        new winston.transports.File({ filename: './logs/bitcoin.log' })
    ]
});

@Fuco1
Copy link

Fuco1 commented Dec 4, 2017

This is so extremly complicated for the simplest requirement of just printing a timestamp (which should be default anyway) :/

@jimwhurr
Copy link

jimwhurr commented Dec 5, 2017

Here's what I do...

//logger.js

const winston = require('winston');
const moment = require('moment');

// create formatter for dates used as timestamps
//const tsFormat = () => (new Date()).toLocaleTimeString();
const tsFormat = () => moment().format('YYYY-MM-DD hh:mm:ss').trim();

// define a logger with 2 transports - console and a file
const logger = new (winston.Logger)({
  transports: [
    // colorize the output to the console
    new (winston.transports.Console)({
    	timestamp: tsFormat,
    	colorize: true
    }),
    new winston.transports.File({
    	filename: './logs/ttracker.log',
    	timestamp: tsFormat,			// makes timestamp 'pretty'
    	json: false					// makes log format just like console output
	})
  ]
});

// set logging level one of { error: 0, warn: 1, info: 2, verbose: 3, debug: 4, silly: 5 }
logger.level = 'debug';

module.exports = logger;

@jimwhurr
Copy link

jimwhurr commented Dec 6, 2017

P.S. I only set timestamp: to a function because I don't like the default format which you get by setting timestamp: true, i.e. 2017-12-05T08:22:09.179Z

@a-h
Copy link

a-h commented Dec 7, 2017

@jimwhurr - for me, your code (node v6.11.0) produces:

Error: winston.Logger was moved in winston@3.0.0.
Use a winston.createLogger instead.
    at new <anonymous> (/Users/adrian/Documents/winston_test/node_modules/winston/lib/winston/common.js:162:15)
    at Object.<anonymous> (/Users/adrian/Documents/winston_test/index.js:7:16)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:389:7)
    at startup (bootstrap_node.js:149:9)

@a-h
Copy link

a-h commented Dec 7, 2017

Taking the examples here, I created a simpler standalone example:

https://gist.github.com/a-h/d02bd4ff238e5923fcf5369233e51401

const winston = require('winston');
const MESSAGE = Symbol.for('message');

const jsonFormatter = (logEntry) => {
  const base = { timestamp: new Date() };
  const json = Object.assign(base, logEntry)
  logEntry[MESSAGE] = JSON.stringify(json);
  return logEntry;
}

const logger = winston.createLogger({
  level: 'info',
  format: winston.format(jsonFormatter)(),
  transports: new winston.transports.Console(),
});

logger.info('message content', { "context": "index.js", "metric": 1 })
logger.info('message content 2')

Output:

{"timestamp":"2017-12-07T16:07:10.518Z","context":"index.js","metric":1,"level":"info","message":"message content"}
{"timestamp":"2017-12-07T16:07:10.520Z","message":"message content 2","level":"info"}

@kedrovski
Copy link

kedrovski commented Feb 3, 2018

Hi, here is another option for logging with timestamp (tested on 3.0.0-rc0):

const winston = require('winston');
var customFormat = winston.format.combine(
winston.format(
function dynamicContent(info, opts) {
info.level = 'info';
if(info.time) {
var dt = new Date(),
date_now = dt.getDate() < 10 ? '0'+ dt.getDate() : dt.getDate(),
month_now = (dt.getMonth() + 1) < 10 ? '0'+ (dt.getMonth() + 1) : (dt.getMonth() + 1),
year_now = dt.getFullYear(),
hrs_now = dt.getHours(),
mins_now = dt.getMinutes(),
secs_now = dt.getSeconds(),
millisec_now = dt.getMilliseconds();
info.time = ' '+date_now+'-'+month_now+'-'+year_now+' '+hrs_now+':'+mins_now+':'+secs_now+':'+millisec_now+' ';
}
return info;
}
)(),
winston.format.simple() //format output, also posible use: .json() (instead of .simple)
);

const logger = winston.createLogger({
level: 'info',
format: customFormat,
transports: [
new winston.transports.File({ filename: 'logs.log' })
]
});
module.exports = logger;`

And for log:

logger.log({ time: true, level: 'info', message: 'message for logging' });

May be it will be helpful.

@felipemullen
Copy link

felipemullen commented Mar 1, 2018

you can customize the timestamp with a format string:

winston.createLogger({
    level: ...
    format: winston.format.combine(
        winston.format.label({ label: '[my-label]' }),
        winston.format.timestamp({
            format: 'YYYY-MM-DD HH:mm:ss'
        }),
        winston.format.simple()
    ),
    transports: ...
});

@ricardoaat
Copy link

ricardoaat commented Mar 10, 2018

winston.createLogger({
    level: ...
    format: winston.format.combine(
        winston.format.label({ label: '[my-label]' }),
        winston.format.timestamp({
            format: 'YYYY-MM-DD HH:mm:ss'
        }),
        winston.format.simple()
    ),
    transports: ...
});

This should be on the docs. @felipemullen Thank you!

@indexzero
Copy link
Member

@felipemullen thanks for providing that sample. Agree with @ricardoaat this should be in the docs, so ... now it is: examples/custom-timestamp.js

@hosseinGanjyar
Copy link

hosseinGanjyar commented May 14, 2018

@youngkylejan oh oh.....That's good help...
But I've a problem...what's {} in end of log?

[2018-05-14 04:39:52] [INFO] API running on localhost:3000 {}

@dandv
Copy link
Contributor

dandv commented Jul 8, 2018

I'm new to Winston and, gotta say, the docs are surprisingly hard to follow :(

Somehow, I ended up with the following apparently simpler solution:

winston.createLogger({
    level: ...
    format: winston.format.printf(info => `${new Date().toISOString()} ${info.message}`),
    transports: ...
});

@Gujie-Novade
Copy link

@hosseinGanjyar
Change
info[MESSAGE] = info.message + ' ' + JSON.stringify(...);
to just
info[MESSAGE] = info.message;

@ChristianRich
Copy link

ChristianRich commented Jul 18, 2018

This worked for me.

Setup:

  • JSON logs
  • Timestamps
  • Log rotation
  • File and console logging
import winston from 'winston';
import DailyRotateFile from 'winston-daily-rotate-file';
import fs from 'fs';
import path from 'path';

const LOG_DIR = path.normalize(`${process.cwd()}/logs`);

if (!fs.existsSync(LOG_DIR)) {
  fs.mkdirSync(LOG_DIR);
}

const logger = winston.createLogger({
  exitOnError: false,
  silent: process.env.SUPPRESS_LOGS,
  level: process.env.LOG_LEVEL || 'info',
  format: winston.format.combine(
    winston.format.timestamp({
      format: 'YYYY-MM-DD HH:mm:ss',
    }),
    winston.format.json(),
  ),
  transports: [
    new winston.transports.Console(),
    new DailyRotateFile({
      dirname: LOG_DIR,
      filename: '%DATE%.log',
      datePattern: 'YYYY-MM-DD-HH',
      zippedArchive: false,
      maxSize: '1m',
      maxFiles: '14d',
    }),
  ],
});

export default logger;

@nathanbussey
Copy link

nathanbussey commented Aug 15, 2018

This is all for winston 3.0.0 and @types/winston 2.3.9

const consoleFormat = winston.format.printf(info => {
    const d = new Date();
    const timestamp = d.toLocaleTimeString();
    return `${timestamp} ${info.level}: ${info.message}`;

this returns a timestamp that is just the time in the current timezone.
for fileFormat I use

const timestamp = `${d.toISOString()} (${d.toLocalTimeString()})`;

then

const logger = winston.createLogger({
    level: "debug",
    format: fileFormat,
    transports: [ new winston.transports.File({ filename: "yourname.log", level: "debug"}) ]
});

probably doesn't need level twice. but that's what I'm using currently.

@Enado95
Copy link

Enado95 commented Nov 16, 2018

you can customize the timestamp with a format string:

winston.createLogger({
    level: ...
    format: winston.format.combine(
        winston.format.label({ label: '[my-label]' }),
        winston.format.timestamp({
            format: 'YYYY-MM-DD HH:mm:ss'
        }),
        winston.format.simple()
    ),
    transports: ...
});

Life saver. Many thanks!!!

@antonovicha
Copy link

antonovicha commented Mar 2, 2020

For those who are here to find out how to customize format string besides YYYY-MM-DD HH:mm:ss: winston uses fecha under the hood, so you can refer to fecha documentation.

Mizumaki pushed a commit to Mizumaki/winston that referenced this issue Jun 11, 2020
@rskvazh
Copy link

rskvazh commented Dec 18, 2020

All those examples remove rest parameters in logs. If you want to use format.simple() and only add timestamp to the beginning and remove from rest, this might works for you:

const simpleFormat = format.simple()
const MESSAGE = Symbol.for('message')
const simpleTimestamp = format(info => {
  const { timestamp, ...rest } = info
  const simpled = simpleFormat.transform(rest)
  if (typeof simpled !== 'boolean') {
    // @ts-ignore
    simpled[MESSAGE] = `${timestamp} ${simpled[MESSAGE]}`
  }
  return simpled
})

logger.add(new transports.Console({
  format: format.combine(
      format.timestamp(),
      format.colorize(),
      simpleTimestamp(),
  ),
}))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests