2013-07-17 12 views
8

私は、Expressをフレームワークとして使用し、Winstonをロガーモジュールとして、node.js内のRESTfulなサーバーを開発しています。 このサーバーは大量の同時リクエストを処理します。リクエストIDのようなものを使用して、特定のリクエストごとにログエントリを追跡できることは非常に便利です。ストレートな解決策は、ログエントリを作成するたびにこのIDを別のログ情報として追加するだけですが、サーバーが使用する各メソッドに「要求ID」を渡すことを意味します。Expressのミドルウェアチェーンによるリクエスト(ID別)の識別方法。

node.js/javascriptモジュールがあるかどうか、または特定のリクエストごとにリクエストIDを持ち歩かずに、これを簡単に行うことができる技術があるかどうかを知りたいと思います。

答えて

4

reqは、すべてのリクエストに明示的に付属するオブジェクトを使用できます。
だから、あなたはあなたのアプリケーションで行うと最初のルートは、次のようになります。

var logIdIterator = 0; 

app.all('*', function(req, res, next) { 
    req.log = { 
    id: ++logIdIterator 
    } 
    return next(); 
}); 

そしてどこでも急行の中、あなたはそのidreq内のオブジェクトにアクセスすることができますreq.log.idを。
いくつかのログを作成する関数には、まだいくつかのデータを渡す必要があります。実際には、req.logオブジェクト内にログ機能がある可能性があります。したがって、req.logオブジェクトへのアクセスがある場合にのみロギングが行われることが保証されます。

+1

ありがとうございます。あなたが提案するソリューションを使用することもできます。しかし、私は、適用されるIDを自動的に特定することを念頭に置いていました。私が実装した解決策は、リクエストオブジェクトにIDを格納することでした。カスタムログ機能を呼び出すときには、コールスタックでIDを探します。私はいくつかの理由で間違っていることを知っています(他の関数のパラメータ情報にアクセスすることは "strictモード"では禁止され、効率的ではなく、I/Oイベントが発生したときに新しいスタックを取得する)。 私はそれが可能ではないと思っています。あなたが提案した解決策は、それが最適なものだと思われます。 –

16

自動インクリメントを使用すると、異なるインスタンスで衝突するIDが生成され、アプリを再起動すると自動的にIDの衝突が発生するため、後のログ解析でリクエストを一意に識別できなくなります。

もう1つの解決策があります。

インストールCUID:

npm install --save cuid 

その後、あなたのメインのアプリケーションファイルに:

var cuid = require('cuid'); 
var requestId = function requestId(req, res, next) { 
    req.requestId = cuid(); 
    next(); 
}; 

// Then, at the top of your middleware: 
app.use(requestId); 

は今、あなたが衝突しそうにない優しいリクエストIDを取得します、そしてあなたのことができるようになります複数のインスタンスやサーバーの再起動時にも、ログ分析とデバッグの要求を一意に識別します。

+1

ええ、これは確かに良い解決策ですが、この問題は、IDをwinstonログに公開して、データの重複を避ける方法です。 –

+0

私はまたドメイン(またはドメインを置き換えることを決めたもの)を使用して、コードのレイヤー全体に要求情報を渡すことで関数呼び出しを汚染しないようにします。 – CBP

+0

ドメインは廃止され、置換の具体的な計画はありません。 –

0

グローバル変数は使用しないでください。

私がしたいことは、各リクエストの前にMETAオブジェクトを設定することです。

私は要求

は、ここに私はこの問題の解決のための検索を苦しんでいた例

app.all('*', function(req, res, next) { 
    req.meta = { 
     ip: req.headers['x-forwarded-for'] || req.connection.remoteAddress, 
     timestamp: uuid(), 
     user_agent: req.headers['user-agent'], 
     body: req.body, 
    } 
    return next(); 
    }) 
2

だIDにUUIDジェネレータ(https://github.com/kelektiv/node-uuid)を使用します。 私がここで提案した解決策について気に入らなかったのは、プロジェクトに沿ったすべての機能の中でreqオブジェクトを共有することを意味するということでした。 私はあなたのアプローチ(要求ごとにuuidを作成する)と、モジュール間で名前空間を共有できるライブラリ(継続的なローカルストレージ)を組み合わせたソリューションを見つけました。

あなたは、この他の回答で説明を見つけることができます:https://stackoverflow.com/a/47261545/5710581

あなたはより多くの情報が必要な場合、私は一つの場所ですべてを説明するために、ポスト内のすべてのこれらのアイデアとすべてのコードを書いた: Express.js: Logging info with global unique request ID – Node.js

関連する問題