2016-04-26 14 views
9

各メソッド/関数呼び出しにロガーを渡すことなく、各ログステートメントに含まれる一意の要求Idを定義することは可能ですか?使用中のNodeJS Express - グローバル一意の要求Id

技術:あなたの要求の処理の先頭にNodeJS、エクスプレス、ウィンストン

+0

あなたがES6を使用している場合は、Symbolを使用したい場合は – MayorMonty

+0

が好きでしょうが、今のところ0.10.13に固執しています – smokedice

+0

@MayorMontyどのように役立ちますか? – milan

答えて

6

我々はいくつかのプロジェクトで、これと同じ問題を抱えていた、と私はこの質問のための任意の完全なソリューションをfindeことができませんでした。私たちは同じ技術(ログ用のNode.js、Express.js、Winston)を使用しています 2つのライブラリとWinstonライブラリを使用して、これに対する解決策を見つけました: - 各リクエストに固有のIDを作成するnode-uuid - 継続-local - すべての呼び出しでreqオブジェクトを送信せずに、異なるモジュール間でこのIDを共有するためのストレージ。

まず、リクエストごとに一意のIDを作成して設定する必要があります。私のミドルウェアでそれを行う:私はウィンストンライブラリをラップする必要がありました。その後

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

、コンテキストからIDを回復し、ログのメッセージに追加する:

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() 
}) 

これは与えますすべての要求は一意の(シーケンシャルな)IDです。 人々はそれを使って自分自身を識別できないようにし、内部でのみ使用してください!この

app.use(function(req, res) { 
    winston.log('info', 'Test Log Message', { id: req.id }); 
    res.end("Done.") 
}); 

のように見えます

ウィンストンにログインするとき、あなたは(フォーム${name}=${value}中)のメッセージの後に表示されるように、メタデータを入力することができますが、これは便利です願っています。

+0

これは現在実装されている解決策ですが、要求Idは、要求IDまたはロガーを含むように関連するすべての定義を変更することなく、他のモジュール/関数/メソッド内で可変ではありません。 – smokedice

+0

あなたは単にクッキーを使うことができませんでしたか? – MayorMonty

+0

zクッキーにアクセスするためにreqが必要ないでしょうか? – 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