NodeJS Express - глобальный уникальный идентификатор запроса
Можно ли определить уникальный идентификатор запроса, который включается в каждый оператор журнала, не передавая регистратор каждому вызову метода / функции?
Используемые технологии: NodeJS, Express, Winston
3 ответа
отредактированный
Наконец, я создал библиотеку, которая делает всю работу. https://github.com/davicente/express-logger-unique-req-id
Это оболочка библиотеки Winston, поэтому вы можете использовать ее таким же образом.
Дайте мне знать, если это поможет вам
У нас была такая же проблема в нескольких проектах, и я не мог найти полное решение этого вопроса. Мы используем одни и те же технологии (Node.js, Express.js и Winston для журналов). Я нашел решение этой проблемы, используя несколько библиотек и упаковав библиотеку Winston: - node-uuid для создания уникальных идентификаторов для каждого запроса - continueation-local- хранилище для обмена этими идентификаторами между различными модулями без отправки объекта req во всех вызовах.
Сначала мне нужно создать и установить уникальный идентификатор для каждого запроса. Я делаю это в промежуточном программном обеспечении:
var uuid = require('node-uuid');
var createNamespace = require('continuation-local-storage').createNamespace;
var myRequest = createNamespace('my request');
// Run the context for each request. Assign a unique identifier to each request
app.use(function(req, res, next) {
myRequest.run(function() {
myRequest.set('reqId', uuid.v1());
next();
});
});
После этого мне пришлось обернуть библиотеку Winston, восстановить идентификатор из контекста и добавить в сообщение журнала:
var winston = require('winston');
var getNamespace = require('continuation-local-storage').getNamespace;
// Wrap Winston logger to print reqId in each log
var formatMessage = function(message) {
var myRequest = getNamespace('my request');
message = myRequest && myRequest.get('reqId') ? message + " reqId: " + myRequest.get('reqId') : message;
return message;
};
var logger = {
log: function(level, message) {
winstonLogger.log(level, formatMessage(message));
},
error: function(message) {
winstonLogger.error(formatMessage(message));
},
warn: function(message) {
winstonLogger.warn(formatMessage(message));
},
verbose: function(message) {
winstonLogger.verbose(formatMessage(message));
},
info: function(message) {
winstonLogger.info(formatMessage(message));
},
debug: function(message) {
winstonLogger.debug(formatMessage(message));
},
silly: function(message) {
winstonLogger.silly(formatMessage(message));
}
};
module.exports = logger;
Я думаю, что это было немного сложно, поэтому я решил записать это в посте. Вы можете получить больше информации оттуда: Express.js: регистрация информации с глобальным уникальным идентификатором запроса - Node.js
Я надеюсь, что это поможет с вашей проблемой.
Этот ответ имеет проблему: счетчик возвращается к 0 каждый раз, когда процесс узла перезапускается. Оказывается, там довольно просто обойти. Вы просто добавляете промежуточное программное обеспечение Express, которое помечает каждый запрос, вызванный UUID, с помощью пакета uuid.
Для UUID Pre-2.0
const uuid = require('uuid');
const app = express();
app.use(function (req, next) {
req.id = uuid.v4();
next();
});
Для uuid 3.0+
const uuidv4 = require('uuid/v4');
const app = express();
app.use(function (req, next) {
req.id = uuidv4();
next();
});
В самом начале обработки вашего запроса добавьте что-то вроде следующего (или поместите его в свой собственный файл):
var makeID = (function() {
var index = 0;
return function() {
return index++;
}
})();
app.use(function(req, res, next) {
req.id = makeID()
next()
})
Это даст каждому запросу уникальный (последовательный) идентификатор. Не позволяйте людям идентифицировать себя с этим, только используйте это внутренне!
При входе в Winston вы можете ввести метаданные, которые будут отображаться после сообщения (в форме ${name}=${value}
), который выглядит так
app.use(function(req, res) {
winston.log('info', 'Test Log Message', { id: req.id });
res.end("Done.")
});
Надеюсь, это полезно.