I'm using 3.0.0-rc1 and the docs aren't clear on how to customize the timestamp's format. Please help.
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' })
LevanArabuli, Sonique, dandv, jstevenperry, peterbabinec, fpintaric, tacomoon, Raphyyy, romangromov, mraak, and 7 more reacted with confused emoji
hosseinGanjyar reacted with heart emoji
All reactions
alvaro1728, a-h, royhobbstn, hifall, pattonjh, josecolella, kedrovski, alexwbai, pvanickova, teneon, and 102 more reacted with thumbs up emoji
arieefrachman, akazakou, and AkshayHere reacted with laugh emoji
OrangeCrush reacted with hooray emoji
All reactions
//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 - for me, your code (node v6.11.0) produces:
Error: winston.Logger was moved in [email protected].
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)
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"}
royhobbstn, luizwbr, DanArcari, apandrade, elboletaire, FireLemons, EdwardMan917, and ragazzid reacted with thumbs up emoji
luizwbr, apandrade, YaroslavGrushko, and ragazzid reacted with hooray emoji
All reactions
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.
format: winston.format.combine(
winston.format.label({ label: '[my-label]' }),
winston.format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss'
winston.format.simple()
transports: ...
ajdinm, yuya-iwabuchi, teneon, ericzon, ricardoaat, krisnamargono, miyakoj, LevanArabuli, Holovin, m-slashe, and 63 more reacted with thumbs up emoji
cloudjk and eugene-beliaev reacted with laugh emoji
Enado95, elboletaire, hassanabbas9, MiMEKiZ, mreis1, jmarsal, shrestaz, and cloudjk reacted with hooray emoji
cloudjk and eugene-beliaev reacted with heart emoji
TPiga, jmarsal, shrestaz, micaelillos, and cloudjk reacted with rocket emoji
cloudjk reacted with eyes emoji
All reactions
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!
jstevenperry, omeraloni, adimachmali, apandrade, kstratis, hassanabbas9, MiMEKiZ, ex, aonics, bartvanremortele, and 6 more reacted with thumbs up emoji
dandv reacted with thumbs down emoji
All reactions
ricardoaat, Gimongi, LevanArabuli, inhuman-cpc, erwinowak, pahan35, logi, and albert-schilling reacted with thumbs up emoji
erwinowak reacted with heart emoji
All reactions
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: ...
});
jstevenperry, nathanbussey, fatfatson, adlius, yohanesgultom, uxcode1, austince, and river-hermsen reacted with thumbs up emoji
danihwsr, app-devper, fozcode, and great-elephant reacted with heart emoji
All reactions
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;
cybersupernova, simuty, rbreejen, gleydsonruan, dave7280, TimvanScherpenzeel, and vcoopman reacted with thumbs up emoji
cybersupernova and simuty reacted with hooray emoji
All reactions
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()})`;
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.
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!!!
michaelshiel, kamolins, dragondgold, tejas-hosamani, and gmostert reacted with thumbs up emoji
tejas-hosamani reacted with hooray emoji
tejas-hosamani, vizitys, and rzanetti-cpqd reacted with heart emoji
All reactions
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(),
}))