2016-04-26 3 views
9

Можно ли определить уникальный идентификатор запроса, который включен в каждый оператор журнала, не передавая регистратору каждый вызов функции/функции?NodeJS Express - глобальный уникальный идентификатор запроса

технологии в использовании: NodeJS, Express, Уинстон

+0

Если вы открываете для использования ES6, вы можете использовать 'Symbol' – MayorMonty

+0

Хотелось бы, но я застрял на 0.10.13 на данный момент – smokedice

+0

@MayorMonty, как бы это помогло? – milan

ответ

6

Мы имели такую ​​же проблему в нескольких проектах, и я не мог Finde любого полное решения этого вопрос , Мы используем те же технологии (Node.js, Express.js и Winston для журналов) Я нашел решение для этого, используя пару библиотек и обернув библиотеку Winston: - node-uuid для создания уникальных идентификаторов для каждого запроса - продолжение -local-storage для обмена этими идентификаторами между различными модулями без отправки объекта 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: Logging info with global unique request ID – Node.js

Я надеюсь, что это поможет с вашей проблемой.

0

В самом начале вашей обработки запроса добавить что-то вроде следующего (или положить его в своем собственном файле):

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.") 
}); 

Надеется, что это полезно.

+0

Это решение, которое в настоящее время реализовано, но идентификатор запроса не является переменным в других модулях/функциях/методах без изменения каждого связанного определения, включая идентификатор запроса или регистратор. – smokedice

+0

Не могли бы вы просто использовать куки? – MayorMonty

+0

Не нужен ли req для получения доступа к z cookie? – smokedice

2

The first answer имеет проблему: счетчик возвращается к 0 каждый раз, когда процесс узла перезапускается. Оказывается, это довольно просто сделать с курьерским промежуточным слоем, что теги каждый запрос с именем, используя uuid:

const uuid = require('uuid'); const app = express(); app.use(function (req, next) { req.id = uuid.v4(); next(); });

+0

, этот подход переместил бы проблему от передачи регистратора до каждого объекта, чтобы передать запрос каждому объекту. – smokedice

Смежные вопросы