我使用这样的代码。
const app = require('express')();
const winston = require('winston');
const expressWinston = require('express-winston');
app.use(expressWinston.logger({
transports: [
new winston.transports.Console(),
],
format: winston.format.combine(
winston.format.printf(info => `Date from winston: ${Date.now()} ${info.message}`),
),
expressFormat: true,
}));
app.get('/check', (req, res) => {
console.log(`Date from route: ${Date.now()}`);
res.end('OK');
});
app.listen(3000, () => console.log('Listening...'));
当我试图调用 /check
路由,我在控制台得到了这样的结果。
Date from route: 1588531901238
Date from winston: 1588531901247 GET /check 200 2ms
如你所见,中间件的时间比路由处理程序的时间晚,为什么?
怎么解决这个问题?我需要获得正确的中间件传递顺序。
这个功能在 express-winston 中还不存在,根据这个。发出.
一个变通的办法是,你可以在你的路由之前添加一个中间件来表达,以拦截所有的请求,然后通过你的自定义记录器记录你需要的信息,或者你创建一个 在温斯顿的定制运输. 一个简单的例子就是
function logRequest(req, res, next) {
console.log('Request', req.path, Date.now());
next();
}
app.use(logRequest);
// routes...
问题1.中间件的时间比路由处理程序的时间晚。
如你所见,中间件的时间比路由处理程序的时间晚。为什么?
答案:因为中间件的时间比路由处理程序的时间晚。
这是因为控制台的传输 new winston.transports.Console()
将你的HTTP请求记录到控制台,而不是你的 console.log(<some-text>)
. 这是在下列文件中找到的 快递-温斯顿
使用 expressWinston.logger(options) 创建一个中间件来记录您的 HTTP 请求。
为了证明这一点,让我们看看你的代码和结果。
// Your above code here...
app.get('/check', (req, res) => {
console.log(`Date from route: ${Date.now()}`);
let i = 1;
const handle = setInterval(() => {
console.log('i:', i);
i++;
}, 1000);
setTimeout(() => {
console.log('i before response:', i);
clearInterval(handle);
res.end('OK');
}, 3000);
});
app.listen(3000, () => console.log('Listening...'));
结果
Listening...
Date from route: 1588616514869
i: 1
i: 2
i before response: 3
Date from winston: 1588616517889 GET /check 200 3005ms
从结果中我们看到,你只得到了自定义信息 Date from winston: 1588616065807
从温斯顿到你,我们叫 res.end('OK')
而不是当我们叫 console.log('Date from route: ${Date.now()}');
.
问题2:
如何解决?
答:如何解决?
不使用默认的 console.log
你可以创建自己的记录器,在那里你可以格式化信息,然后stdout。就像这样。
const app = require('express')();
const winston = require('winston');
const { combine, timestamp, printf } = winston.format;
const myFormat = printf(({ message, timestamp }) => {
const customMessage = `Date from winston: ${timestamp}`;
return `${customMessage}\n${message}`;
});
const logger = winston.createLogger({
transports: [
new winston.transports.Console(),
],
format: combine(timestamp(), myFormat)
});
app.get('/check', (req, res) => {
logger.info(`Date from route: ${Date.now()}`);
let i = 1;
const handle = setInterval(() => {
console.log('i:', i);
i++;
}, 1000);
setTimeout(() => {
console.log('i before response:', i);
clearInterval(handle);
res.end('OK');
}, 3000);
});
app.listen(3000, () => console.log('Listening...'));
结果
Listening...
Date from winston: 2020-05-04T18:26:26.508Z
Date from route: 1588616786506
i: 1
i: 2
i before response: 3
在这种情况下,你会看到当你调用 logger.info
而不是当你叫 res.end('OK')
.
总而言之,使用你的自定义记录器来获得你想要的日志外观。