Node.js - How to add timestamp to logs using Winston library?

我要向日志添加时间戳。

实现这一目标的最佳方法是什么?

Thanks.

89148 次浏览

虽然我不认识 Winston 但这是个建议。我使用 Log4js进行日志记录,默认情况下我的日志如下所示

[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'

开发是我的节点进程的环境,[ INFO | FATAL ]是日志级别的

在 log4js 中可以维护不同的日志配置文件。我有开发和生产概况。还有一些日志记录器类型,如滚动文件附加程序、控制台附加程序等。作为一个插件,您的日志文件将是丰富多彩的基于日志级别[跟踪,信息,调试,错误,致命] ;)

Log4js 将覆盖您的 console.log ,现在在0.5 + 中它是一个可配置参数

我自己也在处理同样的问题,有两种方法可以做到这一点。

当您包含 Winston 时,它通常默认添加一个 Console 传输。为了让时间戳在这个默认情况下工作,我需要:

  1. 删除控制台传输并使用时间戳选项再次添加。
  2. 创建自己的 Logger 对象,时间戳选项设置为 true。

第一:

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

第二个,也是更干净的选择:

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

控制台传输的其他一些选项可以找到 here:

  • Level: 此传输应该记录的消息级别(默认为“ debug”)。
  • Static: 指示是否禁止输出的布尔标志(默认为 false)。
  • colorize: Boolean flag indicating if we should colorize output (default false).
  • Time戳: 布尔标志,指示我们是否应该在输出前加上时间戳(默认为 false)。如果指定了 function,则将使用它的返回值而不是时间戳。

您可以使用内置的 直到永远为您的 nodejs 服务器实现带时间戳的日志记录。 启动服务器时,将日志输出作为参数的一部分添加:

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

然后可以在 server.js 中编写 util

server.js

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

对于 out.log 文件,输出如下所示:

下线

15 Mar 15:09:28 - something with timestamp

我们可以使用控制台戳向现有控制台添加时间戳和日志级别: require('console-stamp')(console, '[yyyy-mm-dd HH:MM:ss.l]')

有关详细信息,请参阅 https://github.com/starak/node-console-stamp

有时候默认的时间戳格式对您来说并不方便。 您可以用您的实现覆盖它。

而不是

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>;
}
})
]
});

有关详细信息,请参阅 https://github.com/winstonjs/winston#custom-log-format

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'})
]
});

我使用了‘ format. comb ()’。因为我需要在所有传输上添加时间戳,所以我在 createLogger 中添加了格式化选项,而不是在每个传输中添加。我在控制台和文件(activity.log)上的输出如下:

{"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"}

我们可以像往常一样使用‘ form.comb ()’为这个时间戳添加格式:

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

我们也可以这样做

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;

另一种解决方案是将日志程序封装到一个文件中,该文件导出一些函数,如 logger.info ()、 logger.error ()等,然后您只需要向每个消息日志传递一个额外的键。

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,
warn
}

无论什么文件

const logger = require('./services/loggerService')


logger.info('Hello World!')

你的日志,日志

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

我采用 Biswadev 的答案并创建了一个带字符串的 JSON 对象。这样,如果我需要处理日志后,它将在一个良好的结构化格式。

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,
};

用法:

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

产出:

Log 文件:

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

控制台:

info:    app is running on port 3001